@object-ui/plugin-ai 17.6.0 → 17.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,7 +5,7 @@ AI-powered components for Object UI — form assistance, recommendations, and na
5
5
  ## Features
6
6
 
7
7
  - 🤖 **AI Form Assist** - Intelligent field suggestions and auto-fill for forms
8
- - 💡 **AI Recommendations** - Display AI-generated recommendations in list, grid, or carousel layouts
8
+ - 💡 **AI Recommendations** - Display AI-generated recommendations in list or grid layouts
9
9
  - 🗣️ **Natural Language Query** - Let users query data using natural language
10
10
  - 📦 **Auto-registered** - Components register with `ComponentRegistry` on import
11
11
  - 🎯 **Type-Safe** - Full TypeScript support
@@ -22,41 +22,55 @@ npm install @object-ui/plugin-ai
22
22
 
23
23
  ## Quick Start
24
24
 
25
+ Every component in this package takes exactly one schema object plus optional
26
+ callbacks — `schema` carries the configuration, the callbacks carry the
27
+ behaviour. The schema types ship from `@object-ui/types`.
28
+
25
29
  ```tsx
26
30
  import { AIFormAssist, AIRecommendations, NLQueryInput } from '@object-ui/plugin-ai';
31
+ import type {
32
+ AIFormAssistSchema,
33
+ AIRecommendationItem,
34
+ AIRecommendationsSchema,
35
+ NLQuerySchema,
36
+ } from '@object-ui/types';
37
+
38
+ declare const recommendationsData: AIRecommendationItem[];
39
+
40
+ const contactAssist: AIFormAssistSchema = {
41
+ type: 'ai-form-assist',
42
+ suggestions: [
43
+ { fieldName: 'company', value: 'ObjectStack Inc.', confidence: 0.92 },
44
+ ],
45
+ showConfidence: true,
46
+ };
27
47
 
28
48
  function SmartForm() {
29
49
  return (
30
50
  <div>
31
- <AIFormAssist
32
- formId="new-contact"
33
- objectName="Contact"
34
- fields={['name', 'email', 'company']}
35
- showConfidence
36
- />
51
+ <AIFormAssist schema={contactAssist} />
37
52
  </div>
38
53
  );
39
54
  }
40
55
 
56
+ const productPicks: AIRecommendationsSchema = {
57
+ type: 'ai-recommendations',
58
+ layout: 'grid',
59
+ recommendations: recommendationsData,
60
+ };
61
+
41
62
  function RecommendationsPanel() {
42
- return (
43
- <AIRecommendations
44
- objectName="Product"
45
- maxResults={5}
46
- layout="grid"
47
- recommendations={recommendationsData}
48
- />
49
- );
63
+ return <AIRecommendations schema={productPicks} />;
50
64
  }
51
65
 
66
+ const orderSearch: NLQuerySchema = {
67
+ type: 'nl-query',
68
+ placeholder: 'Ask a question about your orders...',
69
+ suggestions: ['Show orders from last week', 'Top customers by revenue'],
70
+ };
71
+
52
72
  function SearchBar() {
53
- return (
54
- <NLQueryInput
55
- objectName="Order"
56
- placeholder="Ask a question about your orders..."
57
- suggestions={['Show orders from last week', 'Top customers by revenue']}
58
- />
59
- );
73
+ return <NLQueryInput schema={orderSearch} />;
60
74
  }
61
75
  ```
62
76
 
@@ -64,61 +78,146 @@ function SearchBar() {
64
78
 
65
79
  ### AIFormAssist
66
80
 
67
- AI-powered form field suggestions and auto-fill:
81
+ AI-powered form field suggestions and auto-fill. Props: `schema`, plus the
82
+ optional `onApply` and `onRefresh` callbacks.
68
83
 
69
84
  ```tsx
70
- <AIFormAssist
71
- formId="new-lead"
72
- objectName="Lead"
73
- fields={['name', 'email', 'phone']}
74
- autoFill={false}
75
- showConfidence
76
- showReasoning={false}
77
- />
85
+ import { AIFormAssist } from '@object-ui/plugin-ai';
86
+ import type { AIFormAssistSchema } from '@object-ui/types';
87
+
88
+ const leadAssist: AIFormAssistSchema = {
89
+ type: 'ai-form-assist',
90
+ suggestions: [
91
+ { fieldName: 'phone', value: '+86 21 0000 0000', confidence: 0.71, reasoning: 'Matched the company record' },
92
+ ],
93
+ showConfidence: true,
94
+ showReasoning: false,
95
+ };
96
+
97
+ const assistPanel = (
98
+ <AIFormAssist
99
+ schema={leadAssist}
100
+ onApply={(suggestion) => console.log(suggestion.fieldName, suggestion.value)}
101
+ />
102
+ );
78
103
  ```
79
104
 
80
105
  ### AIRecommendations
81
106
 
82
- Display AI-generated recommendations:
107
+ Display AI-generated recommendations. Props: `schema`, plus the optional
108
+ `onSelect` and `onDismiss` callbacks.
83
109
 
84
110
  ```tsx
85
- <AIRecommendations
86
- objectName="Product"
87
- recommendations={data}
88
- maxResults={10}
89
- layout="list" // 'list' | 'grid' | 'carousel'
90
- showScores={false}
91
- emptyMessage="No recommendations available"
92
- />
111
+ import { AIRecommendations } from '@object-ui/plugin-ai';
112
+ import type { AIRecommendationItem, AIRecommendationsSchema } from '@object-ui/types';
113
+
114
+ declare const data: AIRecommendationItem[];
115
+
116
+ const productPicks: AIRecommendationsSchema = {
117
+ type: 'ai-recommendations',
118
+ recommendations: data.slice(0, 10), // every item handed over is rendered
119
+ layout: 'list', // 'list' | 'grid'
120
+ showScores: false,
121
+ emptyMessage: 'No recommendations available',
122
+ };
123
+
124
+ const panel = (
125
+ <AIRecommendations schema={productPicks} onSelect={(item) => console.log(item.id)} />
126
+ );
93
127
  ```
94
128
 
95
129
  ### NLQueryInput
96
130
 
97
- Natural language query input for data exploration:
131
+ Natural language query input for data exploration. Props: `schema`, plus the
132
+ optional `onSubmit` callback.
98
133
 
99
134
  ```tsx
100
- <NLQueryInput
101
- objectName="Order"
102
- placeholder="Ask anything..."
103
- suggestions={['Recent orders', 'Revenue by month']}
104
- showHistory={false}
105
- />
135
+ import { NLQueryInput } from '@object-ui/plugin-ai';
136
+ import type { NLQuerySchema } from '@object-ui/types';
137
+
138
+ const orderSearch: NLQuerySchema = {
139
+ type: 'nl-query',
140
+ placeholder: 'Ask anything...',
141
+ suggestions: ['Recent orders', 'Revenue by month'],
142
+ showHistory: false,
143
+ };
144
+
145
+ const searchBar = <NLQueryInput schema={orderSearch} onSubmit={(query) => console.log(query)} />;
106
146
  ```
107
147
 
108
- ### Schema-Driven Usage
148
+ ## Schema-Driven Usage
109
149
 
110
- Components auto-register with `ComponentRegistry`:
150
+ Components auto-register with `ComponentRegistry` on import. The registry key is
151
+ the schema's `type`, and it is **not** always the component name — `NLQueryInput`
152
+ registers as `nl-query`:
153
+
154
+ | Component | Registry `type` | Schema type |
155
+ |---|---|---|
156
+ | `AIFormAssist` | `ai-form-assist` | `AIFormAssistSchema` |
157
+ | `AIRecommendations` | `ai-recommendations` | `AIRecommendationsSchema` |
158
+ | `NLQueryInput` | `nl-query` | `NLQuerySchema` |
111
159
 
112
160
  ```json
113
161
  {
114
162
  "type": "ai-form-assist",
115
- "formId": "new-contact",
116
- "objectName": "Contact",
117
- "fields": ["name", "email"],
118
- "showConfidence": true
163
+ "showConfidence": true,
164
+ "showReasoning": true
119
165
  }
120
166
  ```
121
167
 
168
+ ## Localization
169
+
170
+ The components read their built-in copy (button labels, headings, the empty
171
+ and loading states, the default `placeholder` and `emptyMessage`) from the
172
+ `ai.*` namespace of `@object-ui/i18n`, so they follow the language of the
173
+ `I18nProvider` they are mounted under. With no provider they render English.
174
+
175
+ Dates (the `nl-query` history) and percentages (confidence and score badges)
176
+ are formatted in the display locale — `useDisplayLocale()` from
177
+ `@object-ui/i18n`: the tenant's regional locale when one is configured, the UI
178
+ language otherwise — never in the machine's locale (objectui#10232).
179
+
180
+ ## What these components do not do
181
+
182
+ They are **presentation only**: each one renders the data on its schema and
183
+ reports the user's decisions through its callbacks. None of them fetches, none
184
+ of them queries, and none of them caps a list.
185
+
186
+ `formId`, `objectName`, `fields`, `autoFill` and `maxResults` were declared,
187
+ offered in the designer and taught here — and read by nothing, at any depth.
188
+ They are retired (objectui#8178, ADR-0049, director decision batch #78,
189
+ 2026-09-07) and are refused by the schema types now, so a node that carries one
190
+ is a compile error rather than a silent no-op:
191
+
192
+ | Key | Was on | Instead |
193
+ |---|---|---|
194
+ | `formId` | `AIFormAssistSchema` | the host owns the form; pass `suggestions` in and act on `onApply` |
195
+ | `objectName` | all three schemas | scope the query in the host that answers it |
196
+ | `fields` | `AIFormAssistSchema` | each suggestion names its own `fieldName` |
197
+ | `autoFill` | `AIFormAssistSchema` | apply the suggestions you want from `onApply` |
198
+ | `maxResults` | `AIRecommendationsSchema` | slice `recommendations` before handing it over — **every item is rendered** |
199
+
200
+ Four more keys went the same way (objectui#10874), on seven member slots. `config` and `context`
201
+ were read by nothing: none of these components calls a model, so neither
202
+ configured anything. `onApplySuggestion` and `onRejectSuggestion` were typed
203
+ `string` and read by nothing either. All four are now refused by the schema
204
+ types and by the validator alike:
205
+
206
+ | Key | Was on | Instead |
207
+ |---|---|---|
208
+ | `config` | all three schemas | configure the model in your host's own AI service (ObjectUI has no AI-provider API; these components call no model), and hand its output to the node as `suggestions`, `recommendations` or `result` |
209
+ | `context` | `AIFormAssistSchema`, `AIRecommendationsSchema` | pass it to your host's own AI service when you ask it for suggestions or recommendations |
210
+ | `onApplySuggestion` | `AIFormAssistSchema` | the `onApply` component prop |
211
+ | `onRejectSuggestion` | `AIFormAssistSchema` | delete it — the component has no reject callback |
212
+
213
+ `onSelect` and `onDismiss` (`AIRecommendationsSchema`) and `onSubmit`
214
+ (`NLQuerySchema`) were typed `string` too, but the components DO call them:
215
+ a string there was called as a function and threw at click. They are now typed
216
+ as the callbacks the components invoke — `(item) => void` and
217
+ `(query) => void` — so pass a function, either as the component prop of the same
218
+ name or on a node you build in TypeScript. The validator still refuses them in
219
+ a JSON document, because JSON has no function value.
220
+
122
221
  ## Links
123
222
 
124
223
  - 📚 [Documentation](https://www.objectui.org/docs/plugins/plugin-ai)
@@ -9,6 +9,16 @@ export interface AIFormAssistProps {
9
9
  }
10
10
  /**
11
11
  * AIFormAssist - AI-powered form filling assistant
12
- * Provides intelligent field suggestions based on context and historical data.
12
+ *
13
+ * Renders the `suggestions` it is handed and reports the author's decisions
14
+ * through `onApply`; it generates nothing and fetches nothing. The whole read
15
+ * surface is the destructure below — `suggestions`, `showConfidence`,
16
+ * `showReasoning`.
17
+ *
18
+ * `autoFill` used to be destructured here with a default and never referenced
19
+ * again, so nothing was ever filled automatically. It is retired along with
20
+ * `formId`, `objectName` and `fields` (objectui#8178, ADR-0049, director
21
+ * decision batch #78) and is a `?: never` tombstone on `AIFormAssistSchema`.
22
+ * Applying a suggestion is the author's act, through `onApply`.
13
23
  */
14
24
  export declare const AIFormAssist: React.FC<AIFormAssistProps>;
@@ -9,6 +9,19 @@ export interface AIRecommendationsProps {
9
9
  }
10
10
  /**
11
11
  * AIRecommendations - AI-powered recommendation component
12
- * Displays intelligent recommendations based on context and user behavior.
12
+ *
13
+ * Renders EVERY item in `schema.recommendations`, in both the `list` and the
14
+ * `grid` layout, and the count badge in the header reports that same length.
15
+ * There is no cap: the caller decides how many items to hand over, and slicing
16
+ * — if it is wanted — happens before the array reaches this component.
17
+ *
18
+ * That sentence replaces a promise this component never honoured.
19
+ * `AIRecommendationsSchema.maxResults` was declared as *"Maximum number of
20
+ * results to display"*, offered in the designer, and read by nothing: a node
21
+ * carrying `maxResults: 5` against a 50-item list rendered 50 rows with no
22
+ * diagnostic. The key is retired (objectui#8178, ADR-0049, director decision
23
+ * batch #78) rather than implemented, because nothing pulled on it; it is a
24
+ * `?: never` tombstone on the schema now, and the behaviour stated here is
25
+ * pinned by `AIRecommendations.rendersEveryItem-8178.test.tsx`.
13
26
  */
14
27
  export declare const AIRecommendations: React.FC<AIRecommendationsProps>;
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { AIFormAssist } from './AIFormAssist';
2
- import { AIRecommendations } from './AIRecommendations';
3
- import { NLQueryInput } from './NLQueryInput';
1
+ import { AIFormAssist } from './AIFormAssist.js';
2
+ import { AIRecommendations } from './AIRecommendations.js';
3
+ import { NLQueryInput } from './NLQueryInput.js';
4
4
  export { AIFormAssist, AIRecommendations, NLQueryInput };