@nocobase/plugin-ai 2.3.0-beta.3 → 3.0.0-alpha.11

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 (170) hide show
  1. package/dist/ai/docs/nocobase/ai/ai-quick-start.md +1 -1
  2. package/dist/ai/docs/nocobase/ai/claude-code/index.md +1 -1
  3. package/dist/ai/docs/nocobase/ai/codex/index.md +1 -1
  4. package/dist/ai/docs/nocobase/ai/hermes-agent/index.md +1 -1
  5. package/dist/ai/docs/nocobase/ai/index.md +6 -25
  6. package/dist/ai/docs/nocobase/ai/install-nocobase-app.md +1 -1
  7. package/dist/ai/docs/nocobase/ai/openclaw/index.md +1 -1
  8. package/dist/ai/docs/nocobase/ai/opencode/index.md +1 -1
  9. package/dist/ai/docs/nocobase/ai/quick-start.mdx +9 -7
  10. package/dist/ai/docs/nocobase/ai/workbuddy/index.md +1 -1
  11. package/dist/ai/docs/nocobase/ai-builder/ai-portal/agent-workflow.md +153 -0
  12. package/dist/ai/docs/nocobase/ai-builder/ai-portal/components.md +134 -0
  13. package/dist/ai/docs/nocobase/ai-builder/ai-portal/deploy.md +164 -0
  14. package/dist/ai/docs/nocobase/ai-builder/ai-portal/index.md +144 -0
  15. package/dist/ai/docs/nocobase/ai-builder/ai-portal/model-selection.md +120 -0
  16. package/dist/ai/docs/nocobase/ai-builder/ai-portal/project-structure.md +128 -0
  17. package/dist/ai/docs/nocobase/ai-builder/index.md +73 -32
  18. package/dist/ai/docs/nocobase/ai-builder/ui-builder.md +2 -0
  19. package/dist/ai/docs/nocobase/ai-dev/index.md +2 -1
  20. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/complete-example.md +206 -0
  21. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/define-ai-employee.md +149 -0
  22. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/define-skill.md +138 -0
  23. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/define-tool.md +189 -0
  24. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/frontend-tool-ui.md +296 -0
  25. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/index.md +126 -0
  26. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/internationalization.md +88 -0
  27. package/dist/ai/docs/nocobase/ai-employees/dev/ai-employee/troubleshooting.md +86 -0
  28. package/dist/ai/docs/nocobase/ai-employees/{knowledge-base/dev → dev/knowledge-base}/external-knowledge-base.md +2 -2
  29. package/dist/ai/docs/nocobase/ai-employees/knowledge-base/knowledge-base/index.md +1 -1
  30. package/dist/ai/docs/nocobase/api/app/env.md +1 -1
  31. package/dist/ai/docs/nocobase/api/cli/index.md +14 -2
  32. package/dist/ai/docs/nocobase/api/cli/portal/config.md +46 -0
  33. package/dist/ai/docs/nocobase/api/cli/portal/create.md +45 -0
  34. package/dist/ai/docs/nocobase/api/cli/portal/deploy.md +39 -0
  35. package/dist/ai/docs/nocobase/api/cli/portal/destroy.md +43 -0
  36. package/dist/ai/docs/nocobase/api/cli/portal/dev.md +51 -0
  37. package/dist/ai/docs/nocobase/api/cli/portal/index.md +142 -0
  38. package/dist/ai/docs/nocobase/api/cli/portal/info.md +41 -0
  39. package/dist/ai/docs/nocobase/api/cli/portal/list.md +40 -0
  40. package/dist/ai/docs/nocobase/api/cli/portal/pull.md +53 -0
  41. package/dist/ai/docs/nocobase/api/cli/portal/push.md +41 -0
  42. package/dist/ai/docs/nocobase/development/index.md +1 -1
  43. package/dist/ai/docs/nocobase/get-started/installation/env.md +1 -1
  44. package/dist/ai/docs/nocobase/nocobase-cli/installation/cli.md +1 -1
  45. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-bulk-edit/index.md +1 -1
  46. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-bulk-update/index.md +1 -1
  47. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-custom-request/index.md +1 -1
  48. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-duplicate/index.md +1 -1
  49. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-export/index.md +1 -1
  50. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-import/index.md +1 -1
  51. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-action-print/index.md +1 -1
  52. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-ai/index.md +1 -1
  53. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-ai-gigachat/index.md +1 -1
  54. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-api-doc/index.md +1 -1
  55. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-api-keys/index.md +1 -1
  56. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-async-task-manager/index.md +1 -1
  57. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-audit-logs/index.md +1 -1
  58. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-auth/index.md +1 -1
  59. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-auth-sms/index.md +1 -1
  60. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-backup-restore/index.md +1 -1
  61. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-backups/index.md +1 -1
  62. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-comment/index.md +1 -1
  63. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-grid-card/index.md +1 -1
  64. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-iframe/index.md +1 -1
  65. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-list/index.md +1 -1
  66. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-markdown/index.md +1 -1
  67. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-multi-step-form/index.md +1 -1
  68. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-template/index.md +1 -1
  69. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-tree/index.md +1 -1
  70. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-block-workbench/index.md +1 -1
  71. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-calendar/index.md +1 -1
  72. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-charts/index.md +1 -1
  73. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-client/index.md +1 -1
  74. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-collection-fdw/index.md +1 -1
  75. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-collection-sql/index.md +1 -1
  76. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-collection-tree/index.md +1 -1
  77. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-comments/index.md +1 -1
  78. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-custom-variables/index.md +1 -1
  79. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-data-source-main/index.md +1 -1
  80. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-data-source-manager/index.md +1 -1
  81. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-data-visualization/index.md +1 -1
  82. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-data-visualization-echarts/index.md +1 -1
  83. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-departments/index.md +1 -1
  84. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-embed/index.md +1 -1
  85. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-environment-variables/index.md +1 -1
  86. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-error-handler/index.md +1 -1
  87. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-attachment-url/index.md +1 -1
  88. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-china-region/index.md +1 -1
  89. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-code/index.md +1 -1
  90. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-formula/index.md +1 -1
  91. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-m2m-array/index.md +1 -1
  92. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-markdown-vditor/index.md +1 -1
  93. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-sequence/index.md +1 -1
  94. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-field-sort/index.md +1 -1
  95. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-file-manager/index.md +1 -1
  96. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-file-previewer-office/index.md +1 -1
  97. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-flow-engine/index.md +1 -1
  98. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-form-drafts/index.md +1 -1
  99. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-gantt/index.md +1 -1
  100. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-graph-collection-manager/index.md +1 -1
  101. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-idp-oauth/index.md +1 -1
  102. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-kanban/index.md +1 -1
  103. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-license/index.md +1 -1
  104. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-locale-tester/index.md +1 -1
  105. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-localization/index.md +1 -1
  106. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-logger/index.md +1 -1
  107. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-map/index.md +1 -1
  108. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-mcp-server/index.md +1 -1
  109. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-mobile/index.md +1 -1
  110. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-mobile-client/index.md +1 -1
  111. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-multi-app-manager/index.md +1 -1
  112. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-multi-app-share-collection/index.md +1 -1
  113. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-multi-keyword-filter/index.md +1 -1
  114. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-notification-email/index.md +1 -1
  115. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-notification-in-app-message/index.md +1 -1
  116. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-notification-manager/index.md +1 -1
  117. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-public-forms/index.md +1 -1
  118. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-snapshot-field/index.md +1 -1
  119. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-system-settings/index.md +1 -1
  120. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-text-copy/index.md +1 -1
  121. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-theme-editor/index.md +1 -1
  122. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-ui-layout/index.md +1 -1
  123. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-ui-schema-storage/index.md +1 -1
  124. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-ui-templates/index.md +1 -1
  125. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-user-data-sync/index.md +1 -1
  126. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-users/index.md +1 -1
  127. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-verification/index.md +1 -1
  128. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow/index.md +1 -1
  129. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-action-trigger/index.md +1 -1
  130. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-aggregate/index.md +1 -1
  131. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-cc/index.md +1 -1
  132. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-custom-action-trigger/index.md +1 -1
  133. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-date-calculation/index.md +1 -1
  134. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-delay/index.md +1 -1
  135. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-dynamic-calculation/index.md +1 -1
  136. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-javascript/index.md +1 -1
  137. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-json-variable-mapping/index.md +1 -1
  138. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-loop/index.md +1 -1
  139. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-mailer/index.md +1 -1
  140. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-manual/index.md +1 -1
  141. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-notification/index.md +1 -1
  142. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-parallel/index.md +1 -1
  143. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-request/index.md +1 -1
  144. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-request-interceptor/index.md +1 -1
  145. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-response-message/index.md +1 -1
  146. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-sql/index.md +1 -1
  147. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-test/index.md +1 -1
  148. package/dist/ai/docs/nocobase/plugins/@nocobase/plugin-workflow-variable/index.md +1 -1
  149. package/dist/client/{244.28ee769f796b7c2f.js → 244.276308c9b2090ec2.js} +1 -1
  150. package/dist/client/{264.cc98933ef65608b6.js → 264.6ca5f2eeb4173d86.js} +1 -1
  151. package/dist/client/index.js +2 -2
  152. package/dist/client-v2/{244.39348a95d627d9e3.js → 244.e85b8d4659ca66c0.js} +1 -1
  153. package/dist/client-v2/{264.be92ff6a4d2612f1.js → 264.3c7d8e90aa7f46ee.js} +1 -1
  154. package/dist/client-v2/index.js +2 -2
  155. package/dist/externalVersion.js +15 -15
  156. package/dist/node_modules/@langchain/mistralai/package.json +1 -1
  157. package/dist/node_modules/@langchain/xai/package.json +1 -1
  158. package/dist/node_modules/fs-extra/package.json +1 -1
  159. package/dist/node_modules/jsonrepair/package.json +1 -1
  160. package/dist/node_modules/just-bash/package.json +1 -1
  161. package/dist/node_modules/nodejs-snowflake/package.json +1 -1
  162. package/dist/node_modules/openai/package.json +1 -1
  163. package/dist/node_modules/zod/package.json +1 -1
  164. package/dist/server/ai-employees/ai-conversations.d.ts +2 -1
  165. package/dist/server/ai-employees/ai-conversations.js +2 -0
  166. package/dist/server/collections/ai-conversations.js +5 -0
  167. package/dist/server/migrations/20260803185305-migrate-ai-conversations-portal-name.d.ts +14 -0
  168. package/dist/server/migrations/20260803185305-migrate-ai-conversations-portal-name.js +52 -0
  169. package/dist/server/resource/aiConversations.js +14 -2
  170. package/package.json +2 -2
@@ -0,0 +1,296 @@
1
+ ---
2
+ title: "Add Frontend Interaction to a Tool"
3
+ description: "Explains frontend interaction for NocoBase AI employee Tools, including cards, modals, decisions.edit, and frontend execution."
4
+ keywords: "NocoBase,Tool frontend card,ToolsUIProperties,decisions.edit,SuggestionsOptionsCard,frontend Tool"
5
+ ---
6
+
7
+ # Add Frontend Interaction to a Tool
8
+
9
+ Some Tools only need to run on the server and require no custom interface. Other Tools need the user to confirm, select, or edit arguments. In those cases, register a frontend card for the Tool with the same name.
10
+
11
+ :::tip Distinguish the two concepts
12
+
13
+ A **frontend card** only handles ToolCall display and human interaction. It does not mean that the Tool's business logic must run in the browser.
14
+
15
+ If the card only displays options like `suggestions` and continues to the server-side `invoke()` after the user selects one, keep the default `execution: 'backend'`. Set `execution: 'frontend'` and implement a frontend `invoke` only when the Tool's actual logic must access the current browser page, FlowModel, or editor state.
16
+
17
+ :::
18
+
19
+ ## Define arguments and execution logic on the server first
20
+
21
+ The built-in `suggestions` Tool is located at:
22
+
23
+ ```text
24
+ packages/plugins/@nocobase/plugin-ai/src/ai/tools/suggestions.ts
25
+ ```
26
+
27
+ Its schema includes both the candidate options and the user's final selection:
28
+
29
+ ```ts
30
+ schema: z.object({
31
+ option: z.string().describe('user selected option, ignore this param').optional(),
32
+ options: z.array(z.string()).describe('A list of suggested prompts for the user to choose from.'),
33
+ })
34
+ ```
35
+
36
+ According to the Tool description, the model should generate only `options` on the first call. Because this Tool does not set `defaultPermission: 'ALLOW'`, its default permission is `ASK`, and the ToolCall pauses for user input.
37
+
38
+ After the user makes a selection, the frontend uses `decisions.edit()` to merge `option` into the original arguments and resume the ToolCall. The server-side `invoke()` then returns the selected content:
39
+
40
+ ```ts
41
+ return {
42
+ status: 'success',
43
+ content: args?.option,
44
+ };
45
+ ```
46
+
47
+ The built-in implementation also writes the selection back to `aiMessages.toolCalls`, so rerendered historical messages can still show which option the user selected.
48
+
49
+ ## Write the card component
50
+
51
+ A frontend card receives `ToolsUIProperties`:
52
+
53
+ ```tsx
54
+ import { useState } from 'react';
55
+ import type { ToolsUIProperties } from '@nocobase/client-v2';
56
+ import { Button, Flex } from 'antd';
57
+
58
+ interface DeveloperChoiceArgs {
59
+ options?: string[] | string;
60
+ option?: string;
61
+ }
62
+
63
+ const parseOptions = (value: DeveloperChoiceArgs['options']): string[] => {
64
+ if (Array.isArray(value)) {
65
+ return value.filter((option): option is string => typeof option === 'string');
66
+ }
67
+ if (typeof value !== 'string') {
68
+ return [];
69
+ }
70
+
71
+ try {
72
+ const parsed = JSON.parse(value) as unknown;
73
+ return Array.isArray(parsed) ? parsed.filter((option): option is string => typeof option === 'string') : [];
74
+ } catch {
75
+ return [];
76
+ }
77
+ };
78
+
79
+ export const DeveloperChoiceCard = ({
80
+ toolCall,
81
+ decisions,
82
+ }: ToolsUIProperties<DeveloperChoiceArgs>) => {
83
+ const [submitting, setSubmitting] = useState(false);
84
+ const options = parseOptions(toolCall.args?.options);
85
+
86
+ const handleSelect = async (option: string) => {
87
+ if (submitting) {
88
+ return;
89
+ }
90
+
91
+ setSubmitting(true);
92
+ try {
93
+ await decisions.edit({
94
+ ...toolCall.args,
95
+ option,
96
+ });
97
+ } finally {
98
+ setSubmitting(false);
99
+ }
100
+ };
101
+
102
+ return (
103
+ <Flex gap="small" wrap="wrap">
104
+ {options.map((option, index) => (
105
+ <Button
106
+ key={`${option}-${index}`}
107
+ disabled={toolCall.invokeStatus !== 'interrupted' || submitting}
108
+ onClick={() => handleSelect(option)}
109
+ >
110
+ {option}
111
+ </Button>
112
+ ))}
113
+ </Flex>
114
+ );
115
+ };
116
+ ```
117
+
118
+ :::warning Note
119
+
120
+ This component demonstrates the general use of `decisions.edit()` and handles repeated clicks and JSON-string arguments. In production, you must also account for read-only conversations, the current active message, and historical selection state in the surrounding chat interface. See the complete implementation in `packages/plugins/@nocobase/plugin-ai/src/client-v2/ai-employees/tools/SuggestionsOptionsCard.tsx`.
121
+
122
+ :::
123
+
124
+ `decisions` provides three operations:
125
+
126
+ | Method | Purpose |
127
+ | --- | --- |
128
+ | `approve()` | Continue with the original arguments |
129
+ | `edit(args)` | Modify the arguments and continue |
130
+ | `reject(message?)` | Reject execution and return the reason to the conversation flow |
131
+
132
+ The built-in `SuggestionsOptionsCard.tsx` also handles these details:
133
+
134
+ - Supports both array and JSON-string forms of `options`
135
+ - Displays a loading state while the ToolCall is still being generated
136
+ - Allows selection only for a ToolCall with the `interrupted` status
137
+ - Disables buttons immediately after a click to prevent duplicate submission
138
+ - Preserves and highlights the selected option in historical messages
139
+ - Allows actions only in the current editable conversation
140
+
141
+ ## Register it in the client plugin
142
+
143
+ The frontend registration name must exactly match the server-side Tool name:
144
+
145
+ ```tsx
146
+ import { Plugin } from '@nocobase/client-v2';
147
+ import { DeveloperChoiceCard } from './ai-employees/tools/DeveloperChoiceCard';
148
+
149
+ export class PluginDeveloperHelperClient extends Plugin {
150
+ async load() {
151
+ this.ai.toolsManager.registerTools('developerChoice', {
152
+ ui: {
153
+ card: DeveloperChoiceCard,
154
+ },
155
+ });
156
+ }
157
+ }
158
+
159
+ export default PluginDeveloperHelperClient;
160
+ ```
161
+
162
+ If the server-side file is `src/ai/tools/developerChoice.ts`, register `developerChoice` here.
163
+
164
+ The built-in `suggestions` registration works the same way:
165
+
166
+ ```ts
167
+ export const suggestionsTool = [
168
+ 'suggestions',
169
+ {
170
+ ui: {
171
+ card: SuggestionsOptionsCard,
172
+ },
173
+ },
174
+ ];
175
+ ```
176
+
177
+ `PluginAIClientV2.load()` then calls `registerPluginAIClientV2BuiltinTools(this.ai.toolsManager)` to merge the card into the same-named Tool definition returned by the server.
178
+
179
+ ## Choose a card, modal, or frontend execution
180
+
181
+ ### Use a card
182
+
183
+ The following lists only the commonly used client-side `ToolsOptions` settings. See the complete type in `packages/core/client-v2/src/ai/tools-manager/types.ts`.
184
+
185
+ ```ts
186
+ type ToolsOptions = {
187
+ ui?: {
188
+ card?: ComponentType<ToolsUIProperties>;
189
+ modal?: {
190
+ title?: string;
191
+ okText?: string;
192
+ Component?: ComponentType;
193
+ footer?: ComponentType;
194
+ hideOkButton?: boolean;
195
+ // modal.props、useOnOk 等配置请查看完整类型。
196
+ };
197
+ };
198
+ invoke?: (app, params) => unknown | Promise<unknown>;
199
+ // useHooks 等其他配置请查看完整类型。
200
+ };
201
+ ```
202
+
203
+ Use `card` first by default.
204
+
205
+ ### Use a modal
206
+
207
+ Add a `modal` only when the content is extensive or requires a large preview or complex argument editing.
208
+
209
+ ### Execute a Tool in the browser
210
+
211
+ If the server-side Tool sets `execution: 'frontend'`, the client must also provide `invoke`. Such Tools are suitable for reading the current page context, editor content, or FlowEngine state. They are not suitable for data writes that require server-side permission enforcement.
212
+
213
+ ## Complete example: Add a selection card to a built-in AI employee
214
+
215
+ After completing [Complete Example: Create a Built-in AI Employee](./complete-example.md), turn `Dev Helper`'s follow-up question into clickable options by defining another Tool named `developerChoice` and registering a frontend card. Put the server-side file at:
216
+
217
+ ```text
218
+ src/ai/ai-employees/dev-helper/skills/welcome-developer/tools/developerChoice.ts
219
+ ```
220
+
221
+ This Tool declares the options and accepts the user's selection:
222
+
223
+ ```ts
224
+ import type { Context } from '@nocobase/actions';
225
+ import { defineTools } from '@nocobase/ai';
226
+ import { z } from 'zod';
227
+
228
+ export default defineTools({
229
+ scope: 'SPECIFIED',
230
+ introduction: {
231
+ title: '{{t("ai.tools.developerChoice.title", { ns: "@nocobase/plugin-developer-helper" })}}',
232
+ about: '{{t("ai.tools.developerChoice.about", { ns: "@nocobase/plugin-developer-helper" })}}',
233
+ },
234
+ definition: {
235
+ name: 'developerChoice',
236
+ description: 'Show a short list of plugin-development directions for the user to choose from.',
237
+ schema: z.object({
238
+ options: z.array(z.string()).min(2).max(4),
239
+ option: z.string().optional(),
240
+ }),
241
+ },
242
+ invoke: async (_ctx: Context, args: { options: string[]; option?: string }) => {
243
+ return {
244
+ status: 'success',
245
+ content: args.option,
246
+ };
247
+ },
248
+ });
249
+ ```
250
+
251
+ Because `developerChoice.ts` is in the `welcome-developer` Skill's `tools/` directory, it is automatically bound to the current Skill. However, binding only means the model can use the Tool; it does not guarantee that the model will call it.
252
+
253
+ Also update the workflow in `SKILLS.md`, replacing the original steps 5–6 with:
254
+
255
+ ```md
256
+ 5. Use `content.name` to write a short welcome message in the same language as the user.
257
+ 6. Call `developerChoice` exactly once with 2–4 plugin-development directions written in the user's language.
258
+ 7. Wait for the user to select an option.
259
+ 8. Continue according to the selected option.
260
+ ```
261
+
262
+ Reuse the `DeveloperChoiceCard` defined above and save it to:
263
+
264
+ ```text
265
+ src/client-v2/ai-employees/tools/DeveloperChoiceCard.tsx
266
+ ```
267
+
268
+ Finally, register it in `src/client-v2/plugin.tsx`:
269
+
270
+ ```tsx
271
+ import { Plugin } from '@nocobase/client-v2';
272
+ import { DeveloperChoiceCard } from './ai-employees/tools/DeveloperChoiceCard';
273
+
274
+ export class PluginDeveloperHelperClient extends Plugin {
275
+ async load() {
276
+ this.ai.toolsManager.registerTools('developerChoice', {
277
+ ui: {
278
+ card: DeveloperChoiceCard,
279
+ },
280
+ });
281
+ }
282
+ }
283
+
284
+ export default PluginDeveloperHelperClient;
285
+ ```
286
+
287
+ After registering the card, rebuild the client. When a conversation reaches `developerChoice`, the ToolCall pauses and displays clickable options.
288
+
289
+ <!-- 需要一张对话中显示 developerChoice 可点击选项的截图 -->
290
+
291
+ ## Related links
292
+
293
+ - [Define a server-side Tool](./define-tool.md) — Define the server-side Tool corresponding to a frontend card
294
+ - [Complete example: Create a built-in AI employee](./complete-example.md) — Complete the basic example without frontend code first
295
+ - [Internationalization for AI employee plugins](./internationalization.md) — Translate Tool and Skill management-interface text
296
+ - [Client Plugin](../../../plugin-development/client/plugin.md) — Learn about the client plugin entry point and `load()`
@@ -0,0 +1,126 @@
1
+ ---
2
+ title: "AI Employee Plugin Development"
3
+ description: "Explains the relationships, directory conventions, and learning path for Tools, Skills, built-in AI employees, and frontend Tool UI in NocoBase plugins."
4
+ keywords: "NocoBase,AI employee plugin development,Tool,Skill,defineAIEmployee,src/ai"
5
+ ---
6
+
7
+ # AI Employee Plugin Development
8
+
9
+ In NocoBase, plugins can make their business capabilities available to AI employees. Three extension points cover different layers:
10
+
11
+ - **Tool** — Performs specific operations such as querying data, calling APIs, and modifying records
12
+ - **Skill** — Tells the model when to use Tools and which steps to follow to complete a task
13
+ - **Built-in AI Employee** — Assembles a role profile, system prompt, Skills, and Tools into an employee that is ready to use
14
+
15
+ Usually, you do not need to call registration APIs manually. Put files in the plugin's conventional `src/ai` directories, and NocoBase automatically scans and registers them when the plugin loads. You only need to register the corresponding frontend component or execution logic in `src/client-v2/plugin.tsx` when a Tool requires a custom card, modal, or browser-side execution.
16
+
17
+ Before you begin, make sure the application has installed and enabled `@nocobase/plugin-ai`. Plugin code can use the types and definition functions provided by `@nocobase/ai` and `@nocobase/actions`.
18
+
19
+ :::tip Prerequisites
20
+
21
+ - [Write your first plugin](../../../plugin-development/write-your-first-plugin.md) — If you are new to plugin development, start with the plugin directory, build, and activation workflow
22
+ - [AI employees](../../index.md) — Learn how to configure and use AI employees first
23
+
24
+ :::
25
+
26
+
27
+ ## Quick index
28
+
29
+ | I want to... | Read this |
30
+ | --- | --- |
31
+ | Let AI call a server-side operation | [Define a server-side Tool](./define-tool.md) |
32
+ | Specify the call sequence for multiple Tools | [Define a Skill](./define-skill.md) |
33
+ | Provide a fixed AI role with a plugin | [Define a built-in AI employee](./define-ai-employee.md) |
34
+ | See how a Tool, Skill, and employee work together | [Complete example: Create a built-in AI employee](./complete-example.md) |
35
+ | Add confirmation, selection, or editing UI to a Tool | [Add frontend interaction to a Tool](./frontend-tool-ui.md) |
36
+ | Add management-interface translations for Tools and Skills | [Internationalization for AI employee plugins](./internationalization.md) |
37
+ | Troubleshoot registration, binding, and execution | [Troubleshooting AI employee plugin development](./troubleshooting.md) |
38
+
39
+ ## Decide which layer to extend first
40
+
41
+ Tools, Skills, and built-in AI employees are not three separate features. They form layers that build on one another from the bottom up. Not every plugin needs to implement all three.
42
+
43
+ ```text
44
+ Tool:让 AI 能执行一个具体动作
45
+
46
+ Skill:让 AI 按固定方法完成一类任务
47
+
48
+ 内置 AI 员工:把这些能力装配成一个固定角色和使用入口
49
+ ```
50
+
51
+ Choose the starting layer based on your requirements:
52
+
53
+ - If AI only needs to query data, call an API, or modify records, defining a Tool is enough
54
+ - If you need to specify Tool call order, confirmation steps, and output format, define a Skill for those Tools
55
+ - If the plugin should provide a fixed role immediately after it is enabled, create a built-in AI employee and bind the corresponding Skills and Tools
56
+
57
+ When all three layers are used, a task follows this sequence:
58
+
59
+ 1. The user gives the AI employee a task
60
+ 2. The AI employee uses its system prompt to decide which Skill is needed
61
+ 3. The Skill tells the model which Tools to call and in what order
62
+ 4. The Tool performs a query, write, or external request and returns the result
63
+ 5. The AI employee prepares the final response from the Tool result
64
+
65
+ A frontend Tool card is not a fourth capability layer. It only adds an interaction UI to a ToolCall when the Tool needs the user to confirm, select an option, or edit arguments.
66
+
67
+ ## Put AI resources under `src/ai`
68
+
69
+ NocoBase discovers a plugin's AI resources by directory convention. With the standard plugin layout, put Tools, Skills, and built-in AI employees under `src/ai`; you do not need to register them one by one in `load()` in `src/server/plugin.ts`.
70
+
71
+ A complete directory can be organized like this:
72
+
73
+ ```text
74
+ src/ai/
75
+ ├── tools/
76
+ │ └── searchDocs.ts
77
+ ├── skills/
78
+ │ └── document-search/
79
+ │ ├── SKILLS.md
80
+ │ └── tools/
81
+ │ └── readDocument.ts
82
+ └── ai-employees/
83
+ ├── translator.ts
84
+ └── developer/
85
+ ├── index.ts
86
+ ├── prompt.md
87
+ ├── skills/
88
+ └── tools/
89
+ ```
90
+
91
+ Each location uses a different registration method:
92
+
93
+ | File or directory | How NocoBase handles it |
94
+ | --- | --- |
95
+ | `src/ai/tools/<name>.ts` | Registers an independent Tool |
96
+ | `src/ai/skills/<name>/SKILLS.md` | Registers a Skill |
97
+ | `tools/` under a Skill directory | Registers Tools and automatically binds them to the current Skill |
98
+ | `src/ai/ai-employees/<name>.ts` | Registers a single-file built-in AI employee |
99
+ | `src/ai/ai-employees/<name>/index.ts` | Registers a directory-based built-in AI employee |
100
+ | `prompt.md` under an AI employee directory | Provides the employee's default system prompt |
101
+ | `skills/` and `tools/` under an AI employee directory | Registers resources and automatically binds them to the current employee |
102
+
103
+ When a plugin loads, NocoBase completes these steps before running the plugin's own `load()` method:
104
+
105
+ 1. Scan and register Tools
106
+ 2. Parse `SKILLS.md` and bind Tools in each Skill directory to that Skill
107
+ 3. Load built-in AI employees and merge the `prompt.md`, Skills, and Tools in each employee directory
108
+
109
+ `src/client-v2` is not part of this automatic scanning convention. Register something there only when a Tool needs a frontend card, modal, or browser-side execution logic.
110
+
111
+ ## Extension points and directory quick reference
112
+
113
+ | Extension point | Responsibility | Default location |
114
+ | --- | --- | --- |
115
+ | Tool | Performs specific operations such as queries, writes, and external requests | `src/ai/**/tools/` |
116
+ | Skill | Specifies the workflow, Tool call order, and output constraints | `src/ai/**/skills/<name>/SKILLS.md` |
117
+ | Built-in AI employee | Defines a fixed role and assembles its system prompt, Skills, and Tools | `src/ai/ai-employees/` |
118
+ | Frontend Tool card | Displays a ToolCall and collects confirmation, edits, or rejection | `src/client-v2/` |
119
+
120
+ Implement the Tool first by default. Add a Skill when you need a fixed workflow, then create a built-in AI employee when you need a fixed role entry point. Add a frontend card only when the Tool requires browser interaction.
121
+
122
+ ## Related links
123
+
124
+ - [Write your first plugin](../../../plugin-development/write-your-first-plugin.md) — Create and run a NocoBase plugin from scratch
125
+ - [AI employees overview](../../index.md) — Learn where to access and use AI employees
126
+ - [Prompt engineering guide](../../configuration/prompt-engineering-guide.md) — Write system prompts and task constraints
@@ -0,0 +1,88 @@
1
+ ---
2
+ title: "Internationalization for AI Employee Plugins"
3
+ description: "Explains internationalization files, translation templates, and current limitations for NocoBase AI employee Tools, Skills, and built-in employee profiles."
4
+ keywords: "NocoBase,AI employee plugin internationalization,Tool introduction,Skill introduction,locale"
5
+ ---
6
+
7
+ # Internationalization for AI Employee Plugins
8
+
9
+ Management-interface text in an AI employee plugin should follow the current interface language. Tools and Skills can use the plugin's own locale files through `introduction`, while AI employee profile fields are handled differently.
10
+
11
+ ## What needs internationalization
12
+
13
+ Usually, you need to internationalize text displayed to administrators or users:
14
+
15
+ - `introduction.title` and `introduction.about` for Tools
16
+ - `introduction.title` and `introduction.about` for Skills
17
+ - Text in frontend cards, modals, and action buttons
18
+
19
+ `definition.name`, `definition.description`, schema descriptions, Skill content, and AI employee system prompts are primarily intended for the model. Do not change a Tool's stable name or workflow content for interface translation.
20
+
21
+ ## Translate Tool and Skill management-interface text
22
+
23
+ A Tool's `introduction` can use the `{{t(...)}}` translation template:
24
+
25
+ ```ts
26
+ introduction: {
27
+ title: '{{t("ai.tools.greetDeveloper.title", { ns: "@nocobase/plugin-developer-helper" })}}',
28
+ about: '{{t("ai.tools.greetDeveloper.about", { ns: "@nocobase/plugin-developer-helper" })}}',
29
+ },
30
+ ```
31
+
32
+ Use the same format in the frontmatter of a Skill's `SKILLS.md`:
33
+
34
+ ```yaml
35
+ introduction:
36
+ title: '{{t("ai.skills.welcomeDeveloper.title", { ns: "@nocobase/plugin-developer-helper" })}}'
37
+ about: '{{t("ai.skills.welcomeDeveloper.about", { ns: "@nocobase/plugin-developer-helper" })}}'
38
+ ```
39
+
40
+ The `ns` value must match the internationalization namespace actually used by the plugin.
41
+
42
+ ## Add locale files
43
+
44
+ Plugin locale files are stored in `src/locale/`. Use the same keys for each language and change only the corresponding text.
45
+
46
+ ### Add English text
47
+
48
+ Add the following to `src/locale/en-US.json`:
49
+
50
+ ```json
51
+ {
52
+ "ai.tools.greetDeveloper.title": "Developer name check",
53
+ "ai.tools.greetDeveloper.about": "Validate the developer name before writing a welcome message.",
54
+ "ai.tools.developerChoice.title": "Developer choices",
55
+ "ai.tools.developerChoice.about": "Ask the developer to choose the next plugin capability.",
56
+ "ai.skills.welcomeDeveloper.title": "Developer welcome",
57
+ "ai.skills.welcomeDeveloper.about": "Welcome a developer and ask what plugin capability they want to build."
58
+ }
59
+ ```
60
+
61
+ ### Add Chinese text
62
+
63
+ Add the following to `src/locale/zh-CN.json`:
64
+
65
+ ```json
66
+ {
67
+ "ai.tools.greetDeveloper.title": "开发者姓名确认",
68
+ "ai.tools.greetDeveloper.about": "在生成欢迎语之前确认开发者姓名。",
69
+ "ai.tools.developerChoice.title": "开发方向选择",
70
+ "ai.tools.developerChoice.about": "让开发者选择下一步要实现的插件能力。",
71
+ "ai.skills.welcomeDeveloper.title": "欢迎开发者",
72
+ "ai.skills.welcomeDeveloper.about": "欢迎开发者,并询问接下来要实现的插件能力。"
73
+ }
74
+ ```
75
+
76
+ ## Current limitations for AI employee profiles
77
+
78
+ The `nickname`, `position`, `bio`, and `greeting` fields in an AI employee profile do not use the `{{t(...)}}` template mechanism above. At runtime, built-in employees currently translate these raw strings in the `@nocobase/plugin-ai` namespace, so third-party plugins should not assume that a custom namespace will take effect automatically.
79
+
80
+ Unless you add separate localization logic, choose one default language for the employee profile and put the interface text for Tools, Skills, and frontend interactions in the plugin's own locale files.
81
+
82
+ ## Related links
83
+
84
+ - [AI employee plugin development](./index.md) — Return to the development guide overview
85
+ - [Define a server-side Tool](./define-tool.md) — Use translation templates in a Tool introduction
86
+ - [Define a Skill](./define-skill.md) — Use translation templates in Skill frontmatter
87
+ - [Define a built-in AI employee](./define-ai-employee.md) — Learn about employee profile fields
88
+ - [Add frontend interaction to a Tool](./frontend-tool-ui.md) — Add interface translations to frontend cards and modals
@@ -0,0 +1,86 @@
1
+ ---
2
+ title: "Troubleshooting AI Employee Plugin Development"
3
+ description: "Troubleshoot NocoBase AI employee Tools, Skills, built-in employees, and frontend Tool cards that are not registered or do not run."
4
+ keywords: "NocoBase,AI employee troubleshooting,Tool not registered,Skill not loaded,frontend card"
5
+ ---
6
+
7
+ # Troubleshooting AI Employee Plugin Development
8
+
9
+ ## The Tool is not registered
10
+
11
+ Check the following in order:
12
+
13
+ - The file is under `src/ai/**/tools/` within the plugin's build scope
14
+ - The file uses the `.ts` or `.js` extension
15
+ - It uses `export default defineTools(...)`
16
+ - The Tool file is not mistakenly named with the `.d.ts` extension
17
+ - There is no duplicate Tool name causing the later registration to be ignored
18
+ - The plugin has been rebuilt and loaded
19
+
20
+ ## The Skill does not appear
21
+
22
+ Check the filename first. It must currently be:
23
+
24
+ ```text
25
+ SKILLS.md
26
+ ```
27
+
28
+ Also confirm that the frontmatter contains a stable `name` and `description`, and that the file is located at `src/ai/**/skills/<skill-name>/SKILLS.md`.
29
+
30
+ ## The Skill loads but cannot call the Tool
31
+
32
+ Check the following:
33
+
34
+ - The Skill's `tools` list includes the Tool name
35
+ - The Tool is in the current Skill's `tools/` directory
36
+ - The Tool filename, `definition.name`, and Skill reference are consistent
37
+ - The `scope` is appropriate for the current binding method
38
+ - The Tool was not skipped because of a duplicate name
39
+
40
+ Binding a Tool only means the model can use it. If the Tool appears in the Skill but the model still does not call it, explicitly state the call timing, parameter requirements, and result-waiting step in the `SKILLS.md` workflow.
41
+
42
+ ## The frontend card does not appear
43
+
44
+ The frontend registration name must exactly match the final server-side Tool name:
45
+
46
+ ```ts
47
+ this.ai.toolsManager.registerTools('developerChoice', options);
48
+ ```
49
+
50
+ Also check:
51
+
52
+ - The custom plugin uses the `src/client-v2/` runtime
53
+ - The card is registered in the client plugin's `load()` method
54
+ - The ToolCall has entered a state supported by the card
55
+ - The card is not disabled by its `invokeStatus` check
56
+ - The client plugin has been rebuilt and loaded
57
+
58
+ ## The Tool does not continue after clicking the card
59
+
60
+ Confirm that one of `approve()`, `edit()`, or `reject()` is called. To write the user's selection back into the arguments, use:
61
+
62
+ ```ts
63
+ await decisions.edit({
64
+ ...toolCall.args,
65
+ option: selectedOption,
66
+ });
67
+ ```
68
+
69
+ Also confirm that the server-side schema allows this field and that `invoke()` reads it.
70
+
71
+ ## Changing `definition.name` has no effect
72
+
73
+ An automatically loaded Tool's name is determined by its filename or directory name. For example:
74
+
75
+ ```text
76
+ src/ai/tools/developerChoice.ts
77
+ ```
78
+
79
+ The final name is `developerChoice`. To rename it, also rename the file, Skill references, AI employee configuration, and frontend registration name.
80
+
81
+ ## Related links
82
+
83
+ - [AI employee plugin development](./index.md) — Return to the development guide overview
84
+ - [Define a server-side Tool](./define-tool.md) — Check Tool naming and registration
85
+ - [Define a Skill](./define-skill.md) — Check Skill and Tool binding
86
+ - [Add frontend interaction to a Tool](./frontend-tool-ui.md) — Check ToolCall and frontend registration
@@ -12,7 +12,7 @@ An external knowledge base plugin does not participate in document upload, segme
12
12
 
13
13
  :::tip Prereading
14
14
 
15
- - [Knowledge base overview](../knowledge-base/) - Understand the boundaries of Local, Readonly, and External knowledge bases
15
+ - [Knowledge base overview](../../knowledge-base/knowledge-base/index.md) - Understand the boundaries of Local, Readonly, and External knowledge bases
16
16
  - [Plugin](../../../plugin-development/server/plugin.md) - Understand server-side plugin lifecycle and `this.app.pm`
17
17
  - [i18n](../../../plugin-development/server/i18n.md) - Prepare translations if the plugin provides a configuration form
18
18
 
@@ -312,7 +312,7 @@ At this point, the external knowledge base plugin can be called by AI employees.
312
312
 
313
313
  ## Related links
314
314
 
315
- - [Knowledge base overview](../knowledge-base/) - Boundaries of Local, Readonly, and External knowledge bases
315
+ - [Knowledge base overview](../../knowledge-base/knowledge-base/index.md) - Boundaries of Local, Readonly, and External knowledge bases
316
316
  - [Plugin](../../../plugin-development/server/plugin.md) - Server-side plugin lifecycle and `this.app.pm`
317
317
  - [i18n](../../../plugin-development/server/i18n.md) - Plugin frontend and server-side translations
318
318
  - [Client plugin development overview](../../../plugin-development/client/index.md) - Client entry, components, and context capabilities
@@ -39,7 +39,7 @@ The three knowledge base types have different capability boundaries:
39
39
  | --- | --- |
40
40
  | Local | Documents, segment files, and vector data are managed by NocoBase. It supports uploading documents in the UI, and also supports creating, updating, deleting, and retrieving knowledge base documents through workflow nodes |
41
41
  | Readonly | Documents and vector data are maintained by an external system. NocoBase cannot maintain this data in the UI or workflows, and only uses the knowledge base as a RAG retrieval source. Currently, PGVector is the only supported vector database |
42
- | External | Documents, vector data, and retrieval logic are all handled by an external system. NocoBase cannot directly maintain documents or vector data. Developers need to provide a plugin and implement the retrieval logic in that plugin, such as connecting to a vector database not yet supported by NocoBase or calling a third-party retrieval API. For development details, see [External Knowledge Base plugin](../dev/external-knowledge-base) |
42
+ | External | Documents, vector data, and retrieval logic are all handled by an external system. NocoBase cannot directly maintain documents or vector data. Developers need to provide a plugin and implement the retrieval logic in that plugin, such as connecting to a vector database not yet supported by NocoBase or calling a third-party retrieval API. For development details, see [External Knowledge Base plugin](../../dev/knowledge-base/external-knowledge-base.md) |
43
43
 
44
44
  Local knowledge bases are recommended by default. Only consider Readonly or External when documents and vector data are already maintained outside NocoBase and NocoBase only needs to read retrieval results.
45
45
 
@@ -107,7 +107,7 @@ For example, to add the `hello` plugin to the `my-nocobase-app` project, the ful
107
107
  PLUGIN_PACKAGE_PREFIX can be configured as:
108
108
 
109
109
  ```bash
110
- PLUGIN_PACKAGE_PREFIX=@nocobase/plugin-,@nocobase-preset-,@my-nocobase-app/plugin-
110
+ PLUGIN_PACKAGE_PREFIX=@nocobase/plugin-,@nocobase/preset-,@my-nocobase-app/plugin-
111
111
  ```
112
112
 
113
113
  Then the mapping between plugin names and package names is as follows: