@love-moon/app-sdk 0.4.2 → 0.5.1

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/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # @love-moon/app-sdk
2
2
 
3
+ ## 0.5.1
4
+
5
+ ## 0.5.0
6
+
7
+ ### Minor Changes
8
+
9
+ - 5fd165b: Align the app SDK ChatView with the Conductor web chat experience: add
10
+ dedicated MessageBubble and QuestionNav components, expand MessageList
11
+ rendering, and reset chat store state on task switch (covering restart).
12
+ Also ship the REST adapter task hooks and an app-sdk integration guide.
13
+
3
14
  ## 0.4.2
4
15
 
5
16
  ## 0.4.1
package/dist/index.d.ts CHANGED
@@ -239,6 +239,18 @@ interface ChatAdapter {
239
239
  interrupt(taskId: string, opts: {
240
240
  targetReplyTo: string;
241
241
  }): Promise<void>;
242
+ /**
243
+ * Optional. Restart the task's AI session. Adapters that don't support
244
+ * restart may omit it — the widget hides all restart affordances (empty-
245
+ * state button + bubble action) when this method is absent.
246
+ *
247
+ * `restartMode` mirrors Conductor's REST contract (e.g. `'refresh_session'`
248
+ * to refresh the running session in place). When omitted the BFF decides
249
+ * the default.
250
+ */
251
+ restart?(taskId: string, opts?: {
252
+ restartMode?: string;
253
+ }): Promise<void>;
242
254
  /** Optional. Adapters that don't support attachments may omit. */
243
255
  uploadAttachment?(taskId: string, file: File | Blob, opts?: {
244
256
  signal?: AbortSignal;
@@ -48,29 +48,25 @@ interface SendMessageInput {
48
48
  * branch on `role` / `metadata` / `attachments` if it wants to. Return any
49
49
  * ReactNode; the SDK still wraps it in `<div class="conductor-bubble">` and
50
50
  * applies role-based alignment / pending styling.
51
- *
52
- * Returning `null` (or `undefined`) renders an empty bubble — equivalent to
53
- * a message with empty content. If you want to suppress the bubble entirely,
54
- * filter the message upstream (e.g. via your own MessageList).
55
51
  */
56
52
  type RenderMessageContent = (message: Message) => ReactNode;
57
53
  interface MessageListProps {
58
54
  labels: ChatViewLabels;
59
55
  /**
60
56
  * Optional override for how each message's content is rendered inside its
61
- * bubble. Defaults to plain text (`message.content`). Pass e.g. a
62
- * `react-markdown` renderer here to enable markdown formatting:
63
- *
64
- * <MessageList
65
- * labels={...}
66
- * renderMessageContent={(m) => (
67
- * <ReactMarkdown remarkPlugins={[remarkGfm]}>{m.content}</ReactMarkdown>
68
- * )}
69
- * />
57
+ * bubble. Defaults to plain text (`message.content`).
70
58
  */
71
59
  renderMessageContent?: RenderMessageContent;
60
+ /** Forwarded to each bubble; see MessageBubble. */
61
+ showAppOriginChip?: boolean;
62
+ /**
63
+ * When true, hide mutating actions (resend / interrupt / restart, including
64
+ * the empty-state restart button). Copy stays available. Mirrors the
65
+ * `readOnly` ChatView prop.
66
+ */
67
+ readOnly?: boolean;
72
68
  }
73
- declare function MessageList({ labels, renderMessageContent }: MessageListProps): react_jsx_runtime.JSX.Element;
69
+ declare function MessageList({ labels, renderMessageContent, showAppOriginChip, readOnly, }: MessageListProps): react_jsx_runtime.JSX.Element;
74
70
 
75
71
  /**
76
72
  * Runtime status pushed by the daemon while a task is in progress.
@@ -171,6 +167,18 @@ interface ChatAdapter {
171
167
  interrupt(taskId: string, opts: {
172
168
  targetReplyTo: string;
173
169
  }): Promise<void>;
170
+ /**
171
+ * Optional. Restart the task's AI session. Adapters that don't support
172
+ * restart may omit it — the widget hides all restart affordances (empty-
173
+ * state button + bubble action) when this method is absent.
174
+ *
175
+ * `restartMode` mirrors Conductor's REST contract (e.g. `'refresh_session'`
176
+ * to refresh the running session in place). When omitted the BFF decides
177
+ * the default.
178
+ */
179
+ restart?(taskId: string, opts?: {
180
+ restartMode?: string;
181
+ }): Promise<void>;
174
182
  /** Optional. Adapters that don't support attachments may omit. */
175
183
  uploadAttachment?(taskId: string, file: File | Blob, opts?: {
176
184
  signal?: AbortSignal;
@@ -222,6 +230,8 @@ interface ChatViewProps {
222
230
  className?: string;
223
231
  /** Disable send/interact (e.g. when task is read-only). */
224
232
  readOnly?: boolean;
233
+ /** Focus the composer on mount / when the task changes. Default `false`. */
234
+ autoFocus?: boolean;
225
235
  }
226
236
  interface ChatViewLabels {
227
237
  statusThinking: string;
@@ -233,6 +243,22 @@ interface ChatViewLabels {
233
243
  interrupt: string;
234
244
  restart: string;
235
245
  loadEarlier: string;
246
+ /** Action-menu label: copy the message text. */
247
+ copy: string;
248
+ /** Action-menu label shown briefly after a successful copy. */
249
+ copied: string;
250
+ /** Action-menu label: re-send a user message's text. */
251
+ resend: string;
252
+ /** Accessible label for the floating "jump to latest" button. */
253
+ scrollToBottom: string;
254
+ /** Accessible label prefix for the question-anchor navigation dots. */
255
+ jumpToQuestion: string;
256
+ /** Empty-state heading shown when the task has no messages yet. */
257
+ emptyTitle: string;
258
+ /** Empty-state body copy shown below the heading. */
259
+ emptyBody: string;
260
+ /** Empty-state / action-menu button to restart the AI session. */
261
+ restartPending: string;
236
262
  }
237
263
  interface ChatViewTheme {
238
264
  accent?: string;
@@ -246,10 +272,12 @@ declare function ChatView(props: ChatViewProps): react_jsx_runtime.JSX.Element;
246
272
 
247
273
  interface MessageInputProps {
248
274
  labels: ChatViewLabels;
249
- /** Disable the send button (useful while a turn is in progress). */
275
+ /** Disable the composer (e.g. read-only task). */
250
276
  disabled?: boolean;
277
+ /** Focus the textarea on mount / when the task changes. */
278
+ autoFocus?: boolean;
251
279
  }
252
- declare function MessageInput({ labels, disabled }: MessageInputProps): react_jsx_runtime.JSX.Element;
280
+ declare function MessageInput({ labels, disabled, autoFocus }: MessageInputProps): react_jsx_runtime.JSX.Element;
253
281
 
254
282
  interface RuntimeStatusBarProps {
255
283
  labels: ChatViewLabels;
@@ -296,6 +324,15 @@ interface ChatContextValue {
296
324
  }) => Promise<void>;
297
325
  interrupt: () => Promise<void>;
298
326
  loadEarlier: () => Promise<void>;
327
+ /**
328
+ * Restart the task's AI session. No-op when the adapter doesn't implement
329
+ * `restart` — check `restartSupported` before surfacing restart UI.
330
+ */
331
+ restart: (opts?: {
332
+ restartMode?: string;
333
+ }) => Promise<void>;
334
+ /** True when the active adapter implements `restart`. */
335
+ restartSupported: boolean;
299
336
  }
300
337
  declare function useChat(): ChatContextValue;
301
338
  interface ChatProviderProps {
@@ -320,6 +357,9 @@ declare function ChatProvider(props: ChatProviderProps): react_jsx_runtime.JSX.E
320
357
  * POST /tasks/:taskId/interrupt
321
358
  * body: { target_reply_to }
322
359
  * → 200
360
+ * POST /tasks/:taskId/restart (optional)
361
+ * body: { restart_mode? }
362
+ * → 200
323
363
  * GET /tasks/:taskId/events
324
364
  * → text/event-stream emitting `data: <ChatEvent JSON>\n\n`
325
365
  *
@@ -350,6 +390,16 @@ interface RestAdapterOptions {
350
390
  eventSource?: typeof globalThis.EventSource;
351
391
  /** Per-request timeout in ms. Default 30_000. */
352
392
  timeoutMs?: number;
393
+ /**
394
+ * Enable the optional `restart()` adapter method. Default `false`.
395
+ *
396
+ * When enabled, `<ChatView>` shows restart affordances (empty-state button +
397
+ * bubble action). You MUST then implement `POST {baseUrl}/tasks/:id/restart`
398
+ * on your BFF (forward to Conductor's `POST /api/tasks/:id/restart`, or call
399
+ * `client.tasks.restart()`), or the control will 404. Left `false`, the
400
+ * widget hides all restart UI.
401
+ */
402
+ enableRestart?: boolean;
353
403
  }
354
404
  declare function createRestAdapter(options: RestAdapterOptions): ChatAdapter;
355
405