Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

- **AI SDUI Chatbot integration** (`@object-ui/plugin-chatbot`): Refactored chatbot plugin to support full AI streaming via `service-ai` backend and `vercel/ai` SDK (`@ai-sdk/react`). New `useObjectChat` composable hook wraps `@ai-sdk/react`'s `useChat` for SSE streaming, tool-calling, and production-grade chat. Auto-detects API mode (when `api` schema field is set) vs legacy local auto-response mode. ChatbotEnhanced component now supports stop, reload, error display, and streaming state indicators. 44 unit tests (19 new hook tests, 10 new streaming tests).

- **New ChatbotSchema fields** (`@object-ui/types`): Extended `ChatbotSchema` with `api`, `conversationId`, `systemPrompt`, `model`, `streamingEnabled`, `headers`, `body`, `maxToolRoundtrips`, and `onError` fields for service-ai integration. Extended `ChatMessage` with `streaming`, `toolInvocations` fields and added `ChatToolInvocation` interface for tool-calling flows.
- **New ChatbotSchema fields** (`@object-ui/types`): Extended `ChatbotSchema` with `api`, `conversationId`, `systemPrompt`, `model`, `streamingEnabled`, `headers`, `requestBody`, `maxToolRoundtrips`, and `onError` fields for service-ai integration. Extended `ChatMessage` with `streaming`, `toolInvocations` fields and added `ChatToolInvocation` interface for tool-calling flows.

- **New Storybook stories for AI chatbot** (`@object-ui/components`): Added `AIStreamingMode`, `AIWithSystemPrompt`, and `AIWithToolCalls` stories demonstrating the new AI SDUI chat modes alongside existing local/demo stories.

Expand All @@ -33,6 +33,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- **TypeScript build error in ObjectManagerPage** (`apps/console`): Fixed `TS2322: Type 'string' is not assignable to type 'DesignerFieldType'` by adding proper type assertion and missing import for `DesignerFieldType`.

- **ChatbotSchema `body` property conflict with BaseSchema** (`@object-ui/types`): Renamed `ChatbotSchema.body` to `requestBody` to resolve `TS2430: Interface 'ChatbotSchema' incorrectly extends interface 'BaseSchema'` — the chatbot's HTTP request body parameter conflicted with `BaseSchema.body` (child schema nodes). Updated all references in `@object-ui/plugin-chatbot` renderer accordingly.

- **Fields package SSR compatibility for Next.js docs site** (`@object-ui/fields`): Added `react/jsx-runtime` to the Vite build externals configuration to prevent it from being bundled. This fixes the `Error: dynamic usage of require is not supported` failure during Next.js static page prerendering of the `/docs/components/overlay/tooltip` page.

- **Dashboard widgets now surface API errors instead of showing hardcoded data** (`@object-ui/plugin-dashboard`, `@object-ui/plugin-charts`):
- **ObjectChart**: Added error state tracking. When `dataSource.aggregate()` or `dataSource.find()` fails, the chart now shows a prominent error message with a red alert icon instead of silently swallowing errors and rendering an empty chart.
- **MetricWidget / MetricCard**: Added `loading` and `error` props. When provided, the widget shows a loading spinner or a destructive-colored error message instead of the metric value, making API failures immediately visible.
Expand Down
4 changes: 2 additions & 2 deletions apps/console/src/pages/system/ObjectManagerPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { useNavigate, useParams } from 'react-router-dom';
import { Button, Badge } from '@object-ui/components';
import { ArrowLeft, Database, Settings2, Link2 } from 'lucide-react';
import { ObjectManager, FieldDesigner } from '@object-ui/plugin-designer';
import type { ObjectDefinition, DesignerFieldDefinition } from '@object-ui/types';
import type { ObjectDefinition, DesignerFieldDefinition, DesignerFieldType } from '@object-ui/types';
import { toast } from 'sonner';
import { useMetadata } from '../../context/MetadataProvider';

Expand Down Expand Up @@ -103,7 +103,7 @@ function toFieldDefinition(field: MetadataField, index: number): DesignerFieldDe
id: field.name || `fld_${index}`,
name: field.name || '',
label: typeof field.label === 'object' ? field.label.defaultValue || field.label.key || '' : (field.label || field.name || ''),
type: field.type || 'text',
type: (field.type || 'text') as DesignerFieldType,
group: field.group || undefined,
Comment on lines 104 to 107
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Casting field.type to DesignerFieldType bypasses type safety without ensuring the value is actually one of the supported field types. Since this comes from loose API metadata (type?: string), it would be safer to validate/narrow the value (e.g., via a small type guard / allowlist) and fall back to 'text' when unknown, instead of asserting.

Copilot uses AI. Check for mistakes.
sortOrder: index,
description: field.description || field.help || undefined,
Expand Down
2 changes: 2 additions & 0 deletions packages/fields/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export default defineConfig({
external: [
'react',
'react-dom',
'react/jsx-runtime',
'@object-ui/components',
'@object-ui/core',
'@object-ui/react',
Expand All @@ -43,6 +44,7 @@ export default defineConfig({
globals: {
react: 'React',
'react-dom': 'ReactDOM',
'react/jsx-runtime': 'jsxRuntime',
'@object-ui/components': 'ObjectUIComponents',
},
},
Expand Down
6 changes: 3 additions & 3 deletions packages/plugin-chatbot/src/renderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useObjectChat } from './useObjectChat';
* - Uses @ai-sdk/react for SSE streaming, tool-calling, and production-grade chat
* - Connects to service-ai backend (e.g., /api/v1/ai/chat)
* - Supports streaming, stop, reload, clear actions
* - Schema fields: api, conversationId, systemPrompt, model, streamingEnabled, headers, body, maxToolRoundtrips
* - Schema fields: api, conversationId, systemPrompt, model, streamingEnabled, headers, requestBody, maxToolRoundtrips
*
* **Legacy Mode** (when `api` is not set):
* - Local auto-response for demo/playground use
Expand Down Expand Up @@ -57,7 +57,7 @@ ComponentRegistry.register('chatbot',
model: schema.model,
streamingEnabled: schema.streamingEnabled,
headers: schema.headers,
body: schema.body,
body: schema.requestBody,
maxToolRoundtrips: schema.maxToolRoundtrips,
Comment on lines 57 to 61
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requestBody is a breaking rename from the previously documented body schema field. If existing saved schemas may still send body as request params, consider adding a backward-compatible fallback (e.g., treat schema.body as request params when it’s a plain object rather than a SchemaNode) so older configs continue working while migrating to requestBody.

Copilot uses AI. Check for mistakes.
onError: schema.onError,
showTimestamp: schema.showTimestamp,
Expand Down Expand Up @@ -260,7 +260,7 @@ ComponentRegistry.register('chatbot-enhanced',
model: schema.model,
streamingEnabled: schema.streamingEnabled,
headers: schema.headers,
body: schema.body,
body: schema.requestBody,
maxToolRoundtrips: schema.maxToolRoundtrips,
onError: schema.onError,
showTimestamp: schema.showTimestamp,
Expand Down
2 changes: 1 addition & 1 deletion packages/types/src/complex.ts
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ export interface ChatbotSchema extends BaseSchema {
/**
* Additional body parameters to include with each API request.
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JSDoc still refers to “body parameters” even though the property was renamed to requestBody. Consider updating the wording to “request body parameters” (or similar) to avoid confusion with BaseSchema.body (child nodes).

Suggested change
* Additional body parameters to include with each API request.
* Additional request body parameters to include with each API request.

Copilot uses AI. Check for mistakes.
*/
body?: Record<string, unknown>;
requestBody?: Record<string, unknown>;
/**
Comment on lines 528 to 532
Copy link

Copilot AI Mar 31, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChatbotSchema was renamed to requestBody, but the runtime Zod validator for Chatbot still defines an API body field (and overrides BaseSchema.body). This leaves validation/JSON-schema behavior inconsistent with the TypeScript interface and reintroduces the same conceptual conflict at runtime (child nodes vs HTTP body params). Update the Zod ChatbotSchema to use requestBody (and keep BaseSchema.body for child schema nodes) so validated schemas match the published types.

Copilot uses AI. Check for mistakes.
* Maximum number of tool-calling round-trips per user message.
* @default 5
Expand Down
Loading