Skip to content

Releases: cloudtrain-ai/packages

v0.12.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 29 Sep 03:50
ed5173e

Times a booking offers appear as buttons under the reply: the visitor taps one instead of typing it.

  • Quick replies under the latest reply, once it has finished streaming - in the web component (and so the React wrapper) and in React Native. Tapping one sends it as the visitor's message, the same as typing it. An older reply's buttons go away as the conversation moves on.
  • Streamed with the reply. When a widget conversation asks for them, the reply comes as server-sent events (stream_format: "events"): its text as it is written, then the quick replies. Nothing extra is requested after the reply.
  • Callers that don't ask get the bare text stream exactly as before.

SDK: chatStream({ onQuickReplies }), and quick_replies on a ChatCompletion message for the non-streaming call.

Needs a CloudTrain server with stream_format: "events" (live on cloudtrain.ai).

v0.11.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 27 Sep 10:39

Phone numbers in the pre-chat form get a country picker, and CloudTrain checks the form when it is sent.

  • Country picker beside a phone field, preselected from the visitor's country (from CloudTrain, else the browser or device region). On the web it is a native select; in React Native, a button that opens a searchable list. No phone library is bundled: the picker is a ~0.9 KB table of countries and dialling codes, with emoji flags and the platform's own country names.
  • Checked by the server. Pressing Continue posts the form to POST /api/v1/leads, which validates every value - the phone with libphonenumber, the same rules as every other lead - and anything wrong is shown under its field.
  • The lead is saved at Continue, so a visitor who fills the form in and leaves is still a lead.
  • The business being out of leads for the month, or the server being unreachable, never stops the visitor from chatting.

SDK: submitLead(), PHONE_COUNTRIES, phoneCountriesByName(), defaultPhoneCountry(), flagEmoji(), countryName(), and Agent.visitor_country.

Needs a CloudTrain server with lead capture (the form only appears when the widget's "Ask for details before the chat" is on).

v0.10.1

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 27 Sep 06:34

@cloudtrain/chatbot-react now declares react and react-dom (>=18) as peer dependencies, so the host app's React is the one used, and frameworks that check for it (rsc-kit) treat the package as client code without a warning.

v0.10.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 26 Sep 22:17

The pre-chat form is set in the CloudTrain dashboard, not in the embed.

Breaking: preChatFields and requirePreChat (require-pre-chat) are removed from the web component, the React wrapper and the React Native widget. An embed now needs only its key.

  • Whether the form shows is the widget's own setting: Ask for details before the chat (Settings → Widgets), sent as pre_chat by GET /api/v1/agent.
  • What it asks is the agent's lead fields (Settings → Lead fields), sent as lead_fields. Each submission becomes a lead in the dashboard, so an embed can no longer ask for fields that would never be saved.
  • An email or a phone number is always required, since a lead is only saved with one.
  • leadCaptured (web) and onLeadCaptured (React Native) stay, for the page's or app's own tracking - a conversion, a pixel. The lead itself is saved by CloudTrain with the first message.
  • SDK: Agent gains lead_fields and pre_chat (both optional, for older servers), and lacksContact() / LeadField are exported.

Upgrading: remove preChatFields and requirePreChat from your embed and turn the setting on for the widget instead.

v0.9.1

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 21 Sep 12:11

Accessibility and a composited launcher animation.

  • The closed chat panel is inert: its close button, message input and footer link no longer sit in the tab order or the accessibility tree while the panel is hidden (Lighthouse "aria-hidden elements contain focusable descendants"). aria-hidden stays for browsers that predate inert.
  • The launcher's attention pulse is a ring on a pseudo-element animating transform and opacity only, so it runs on the compositor instead of re-painting box-shadow on the main thread every frame. Honours prefers-reduced-motion.
  • Dependencies updated (Stencil 4.45, React output target 1.6.2, Tailwind 4.3.3, Jest 30.5). TypeScript stays on 6.x: stencil-tailwind-plugin reads the compiler API from the typescript package, which 7.x no longer exposes.

v0.9.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 09 Jul 10:46

Widget file upload with plan-gated attachment picker.

  • Widget can attach images, audio, and documents via a three-step presigned upload flow (init → PUT to storage → finalize). Files land as inbound channel_messages under the widget's conversation_id so the AI reads their transcription / description / extracted text on the next turn.
  • SDK: uploadFile() and deleteUpload() on the CloudTrain client; Agent.capabilities with allowed_media_types derived from the agent's plan.
  • Widgets (Stencil + React Native): paperclip button, attachment chips with progress state, rendering gated on the plan's allowed media types. Ready attachments snapshot into the user's chat bubble so there's a visual receipt of what was sent.
  • getAgent() now always runs on mount to fetch capabilities.

v0.8.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 04 Jul 01:37

Fixed

  • React camelCase props were undefined under SSR (Next.js). The component now picks up props assigned during hydration: the CloudTrain client is built lazily (keyed on apiKey/baseUrl), the active theme is derived from the theme prop, and agent metadata fetching reacts to a late-arriving apiKey.
  • The generated server wrapper now hydrates with the real React components (clientModule pointed at a module that didn't export them).

Added

  • @cloudtrain/chatbot-react/next entry point for Next.js server-side rendering — renders the chatbot to a Declarative Shadow DOM with props serialized into the server HTML:
    import { CloudtrainChatbot } from "@cloudtrain/chatbot-react/next";
  • Exports map for @cloudtrain/chatbot-react.

Docs

  • React README now documents camelCase props (the kebab-case guidance was a workaround for the SSR bug) and Next.js usage.

v0.7.0

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 03 Jul 20:02

Highlights

Three new widget capabilities plus a set of fixes and dep refresh across all packages.

Features

  • feat(chatbot): lifecycle event callbacks — chatOpened, chatClosed, messageSent, messageReceived, conversationReset, errorOccurred, leadCaptured. Wire the widget into analytics without touching internals. Available across @cloudtrain/chatbot, @cloudtrain/chatbot-react, and @cloudtrain/chatbot-react-native.
  • feat(chatbot): conversation persistence — resumes an in-progress chat across page reloads (web) or app restarts (React Native). Web uses localStorage; RN uses the optional @react-native-async-storage/async-storage peer dep (silently no-ops if not installed). Configurable via persistConversation, persistTtlHours (default 7 days), persistStorageKey.
  • feat(chatbot): pre-chat lead capture — gate the conversation behind a form. Set requirePreChat + preChatFields=[{name, label, type?, required?, placeholder?}] and captured values are merged into meta on every subsequent request. Fires leadCaptured / onLeadCaptured on submit.

Fixes

  • fix(chatbot): normalize pre-chat form input height (fields were inheriting a textarea-height default)
  • fix(chatbot): export CapturedLead so generated components.d.ts can import it

Docs

  • docs(sdk): clarify json_schema constraints on ResponseFormat (additionalProperties: false, every property in required)
  • docs(chatbot-rn): document expo install vs npm install + pod install for AsyncStorage — plain npm install grabs a version that mismatches Expo Go and crashes at runtime

Chores

  • chore: bump deps across packages (@stencil/core 4.43, @stencil/react-output-target 1.6, tailwindcss 4.3.2, marked 18.0.5, @types/node 26, @types/react 19.2, react-native-safe-area-context 5.8)
  • chore(chatbot): dev harness (src/index.html) now exercises all seven events, pre-chat, and persistence for smoke-testing before release

Install

npm install @cloudtrain/chatbot@0.7.0
npm install @cloudtrain/chatbot-react@0.7.0
npm install @cloudtrain/chatbot-react-native@0.7.0
npm install @cloudtrain/sdk@0.7.0

Full Changelog: v0.6.1...v0.7.0

v0.6.1

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 18 May 14:30

Fixes

chatbot: iOS mobile keyboard handling

Mobile chat panel now stays full-screen fixed and only the composer slides up via padding-bottom = visualViewport keyboard inset, mirroring React Native's KeyboardAvoidingView.

  • touchmove preventDefault outside the messages area (real iOS body lock — overflow:hidden alone doesn't stop touch panning on iOS Safari)
  • focus({ preventScroll: true }) prevents iOS auto-scrolling the visual viewport on input focus
  • overscroll-contain on inner scroll regions to stop rubber-band propagation
  • Body scroll lock via position: fixed; top: -scrollY restores scroll on close

No public API changes.

v0.6.0 — JSON Schema structured output

Choose a tag to compare

@ramonmalcolm10 ramonmalcolm10 released this 17 May 18:21

SDK — JSON Schema structured output

The CloudTrain SDK now supports OpenAI-compatible structured output via response_format, with three usage modes:

chat<T>() — non-streaming, auto-parsed

```ts
const completion = await client.chat({
messages,
response_format: { type: "json_schema", json_schema: { name, schema, strict: true } },
});
const email = completion.choices[0].message.content; // typed MarketingEmail
```

chatStream<T>() — streamed, parsed on complete

Chunks fire as raw strings during the stream (for progress UX); onComplete receives the fully-parsed T.

chatStreamPartial<T>() — progressive JSON streaming (CloudTrain extension)

SDK parses the partial-json SSE stream and emits a Partial<T> per event for generative-UI patterns (live form fills, progressive lists, comparison cards).

Types

  • Message<T = string> and ChatCompletion<T = string> are now generic
  • New ResponseFormat type exported
  • All existing call sites are backward compatible (defaults preserve current behavior)

Other

  • 9 new tests covering request serialization, auto-parse, backward compat, buffered + partial streaming, and SSE chunk-boundary handling