Flutter SDK reference
Every public class, what it is for, and the one thing about it that surprises people.
The whole public API. Everything else in the package is private on purpose — if you find yourself importing from src/, tell us what you needed and we will export it properly.
Full generated dartdoc lands on pub.dev with the first published release. This page is the map.
Rendel
The facade. One init per app run.
| Member | Signature | Notes |
|---|---|---|
init | Future<void> init({required String appKey, RendelTheme? theme, List<RendelAction> actions, RendelConfig config}) | Awaited. A key that does not start with rd_pk_ asserts in debug and reports through onLog in release, then disables the copilot for the run — a typo used to cost a silent afternoon. |
open | Future<void> open(BuildContext context) | Presents the thread as a full-height sheet. Returns without presenting when the copilot is disabled. |
close | void close(BuildContext context) | — |
reset | void reset() | Call on logout. Clears the thread and the user, so the next turn is anonymous. Safe to call while the sheet is up. |
registerAction | void registerAction(RendelAction action) | Re-syncs the manifest. |
addContextProvider | void addContextProvider(String key, Future<Map<String, dynamic>> Function() provider) | Called per turn, with a timeout. A slow provider costs its own context, never the turn. |
identify | Future<void> identify({required String userId, Map<String, dynamic>? traits, String? userHmac}) | See Context. |
refreshConfig | Future<void> refreshConfig() | Re-reads the published appearance. The SDK does not hook the app lifecycle itself; call this on foreground if you want a publish to land without a relaunch. |
events | Stream<RendelEvent> | Broadcast. |
theme / config | RendelTheme / RendelConfig | The effective values, after any published config is layered over yours. |
configRevision | ValueNotifier<int> | Ticks when a published config lands and changes what is on screen. |
isEnabled | bool | False when you turned it off in code or the console published a kill switch. |
isInitialized | bool | — |
deviceId | String? | The anonymous per-install id this run is sending. Null before init completes. It is what Support asks for. |
RendelConfig
Everything that is your choice rather than the protocol's. Every field is also the floor for anything published from the console.
| Field | Default | Notes |
|---|---|---|
apiBaseUrl | https://api.rendel.ai | — |
requestTimeout | 30 s | Non-streaming calls. |
streamIdleTimeout | 45 s | How long a turn may go without a single server event. Server pings every 15 s, and the SDK counts them. |
sdkVersion | flutter/0.1.0 | Sent as client.sdk. |
languages | [] | The languages this app is willing to be answered in, in preference order — ['tr', 'en', 'ru']. The device picks from among them; one speaking none of them gets the first, so the order is a decision. Empty hands the choice to the list published from the console, and absent that the copilot answers in whatever it is addressed in. Different from locale, which is one device's setting. |
locale | device's own | BCP-47 (tr, pt-BR). The language the copilot answers in, and the one confirmTemplates is matched on. A message written in another language is still answered in that one. See Locales. |
assistantName | Assistant | The name in the thread header. |
launcherLabel | Ask | The word on the launcher. |
answerPages | true | Each answer is a page of its own: the question is written over the screen and the answer drawn from the top, with back and forward between pages. false keeps the thread, a conversation of bubbles. Since 0.34.0 the default. |
suggestions | [] | Opening prompts. Name things this app can do, in the user's words. |
emptyStateTitle | null | The headline on an empty thread, in your own words. Null keeps the SDK's, translated into the language the copilot answers in. Publishable from Appearance. |
emptyStateBody | null | The line under the empty thread's headline. |
enabled | true | The kill switch in code. Setting it false wins over anything published. Not a security control — the API enforces suspension server-side. |
remoteConfig | true | False pins the copilot to exactly what this object says. |
configStore | null | Where the last good published config is kept between launches. |
deviceIdStore | null | Where the device id is kept between launches. Use a different key from configStore — both sides read and write one string. |
onPickAttachment | built in | Returns an RendelAttachment (bytes, name, media type) from your own picker, replacing the SDK's Photos, Camera and Files; the "+" then opens yours directly. Null uses the built-in. RendelAttachIcon.off removes the control. |
onStopDictating | null | Ends a dictation when the user presses the microphone again. Without it the control cannot be pressed mid-session and the recogniser ends the session itself. |
onDictate | built in | Returns recognised speech as text from your own recogniser, replacing the SDK's speech_to_text; it is handed an onPartial callback to feed the composer while somebody is still speaking. Return null when nobody spoke and throw when the recogniser failed: the SDK words the two differently and logs the error. Null uses the built-in. RendelVoiceIcon.off removes the control. |
onOpenUrl | null | Null opens a card's link in an in-app browser, so the user comes back to the conversation when they close it. Set it to route links yourself, for example to your own product screen. |
strings | by locale | Every word the SDK puts on screen that is not your app's or the model's. Null takes them from locale — Türkçe, Deutsch, Français, Español, العربية, English elsewhere. Set it and you own them: RendelStrings.forLocale('tr').copyWith(confirm: '…') changes one and keeps the rest. |
onLog | null | Point it at your crash reporter. |
RendelAction
What the copilot is allowed to do.
| Field | Type | Notes |
|---|---|---|
name | String | snake_case, asserted. One camelCase name used to reject the entire manifest. |
description | String | The model reads this to decide when to call it. Write it for a colleague, not for a compiler. |
params | RendelSchema | Validated server-side before an invocation exists. |
risk | RendelRisk | read runs silently; write and destructive get a server-built confirmation card. |
handler | RendelHandler? | Future<RendelResult> Function(Map<String, dynamic> params) |
onInvoke | RendelInvocationHandler? | Future<RendelResult> Function(RendelInvocation) — the same thing plus the invocation's id and risk, for idempotency on your side. |
confirmTemplate | String? | Overrides the server's sentence on the confirm card. |
timeout | Duration | Default 15 s, capped at 120 s. |
sandboxResult | Map<String, dynamic>? | Returned instead of running the handler on a test key. |
RendelSchema
Parameter shapes, without hand-writing JSON Schema.
RendelSchema.object({
'order_id': RendelSchema.string(description: 'The order number'),
'reason': RendelSchema.enumOf(['damaged', 'wrong_item', 'other']).optional,
'quantity': RendelSchema.integer().optional,
'tags': RendelSchema.list(RendelSchema.string()),
})string, number, integer, boolean, enumOf, list, object, and raw for anything the helpers do not cover. .optional (or .orAbsent) on any of them.
RendelResult
RendelResult.ok(Map<String, dynamic> data) or RendelResult.fail(String error). The failure string reaches the model, so write it as something the model can act on: "no order with that number" beats "404".
RendelRisk
read, write, destructive. See Actions and risk levels.
RendelInvocation
id, name, params, risk. The id is stable across a retry of the same turn, so it is the natural idempotency key for whatever your handler does.
RendelLauncher
RendelLauncher({String? label}). Draws nothing when the copilot is uninitialised or disabled, so you can leave it in the tree unconditionally.
RendelTheme
See Theming. Built with RendelTheme.fromTokens(...), which derives readable text and border roles from your four colours rather than trusting them — a themeable SDK that does not do this ships unreadable badges.
RendelConfigStore
abstract class RendelConfigStore {
Future<String?> read();
Future<void> write(String value);
}One interface, two uses: RendelConfig.configStore and RendelConfig.deviceIdStore. The package takes no storage dependency — a plugin in an SDK is a plugin in every host's build — so this is the seam. RendelMemoryConfigStore is the default and survives a reset(), not a relaunch.
RendelLogRecord, RendelLogLevel, RendelLog
Where the SDK reports what it could not tell you any other way.
code | When |
|---|---|
invalid_key | appKey does not start with rd_pk_ (or nc_pk_, a key made before the rename). |
handler_failed | An action handler threw. |
handler_timeout | A handler passed its timeout. |
context_provider_timeout | A context provider missed its 300 ms budget. |
context_provider_failed | A context provider threw. |
manifest_sync_failed | The server rejected the manifest. The message carries the field and the reason. |
transport_failed | A network call failed. |
config_unreadable | A published config could not be parsed, or was not legible on this device. |
config_cache_write_failed | The config store threw on write. |
device_id_ephemeral | No deviceIdStore is set, so the device id is new each launch. Debug level, once. |
device_id_store_failed | The store threw or hung. |
usage_description_missing | Info.plist lacks NSMicrophoneUsageDescription or NSSpeechRecognitionUsageDescription, so the built-in microphone is not drawn, or NSCameraUsageDescription, so the "+" offers no Camera. iOS would close the app the first time either was used. |
user_store_failed | The signed-in user could not be stored or read back, so a relaunch starts signed out until the next identify. |
code is stable and safe to switch on; message is for humans and may be reworded.
RendelEvent
opened, closed, messageSent, actionExecuted. For your own analytics.
Rendering your own component
ComponentRegistry.register(String type, ComponentBuilder builder) puts a widget of yours in the catalog's place. RendelTurn, RendelActionButton, RendelChip, RendelControlShell, RendelOverline, RendelPressable, RendelPulse and RendelSwap are exported so it presses, encloses and breathes like a built-in rather than like Material.