@paymanai/payman-ask-sdk 1.2.26 → 2.0.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
@@ -1,249 +1,264 @@
1
- # Payman Ask SDK
1
+ # @paymanai/payman-ask-sdk
2
2
 
3
- A reusable React component library for building chat interfaces powered by Payman workflows.
3
+ React chat component for Payman workflows streaming, verification, voice, and session history out of the box.
4
4
 
5
- ## Features
5
+ > **v2.0 is a clean break from v1.** The configuration API has been nested under `api`, `workflow`, `session`, `availability`, `ui`, and `observability`. See the [Migrating from v1](#migrating-from-v1) section for a translation table.
6
6
 
7
- **Fully Self-Contained** - Handles all API calls, streaming, and state management
8
- ✅ **Type-Safe** - Built with TypeScript for full type safety
9
- ✅ **SSE Streaming** - Real-time message streaming with Server-Sent Events
10
- ✅ **Context API** - Control chat programmatically from parent components
11
- ✅ **Customizable** - Flexible configuration and custom headers
12
- ✅ **Execution Tracing** - Built-in support for execution trace data
13
- ✅ **Session Management** - Automatic session ID generation and tracking
14
- ✅ **Markdown Support** - Rich message formatting with react-markdown
15
- ✅ **Animations** - Smooth animations with Framer Motion
16
-
17
- ## Installation
7
+ ## Install
18
8
 
19
9
  ```bash
20
- npm install @paymanai/payman-ask-sdk
21
- # or
22
- yarn add @paymanai/payman-ask-sdk
23
- # or
24
- bun add @paymanai/payman-ask-sdk
10
+ npm install @paymanai/payman-ask-sdk @paymanai/payman-typescript-ask-sdk
25
11
  ```
26
12
 
27
- ## Quick Start
28
-
29
- ### For Playground/Testing
30
-
31
13
  ```tsx
14
+ import "@paymanai/payman-ask-sdk/styles.css";
32
15
  import { PaymanChat } from "@paymanai/payman-ask-sdk";
33
-
34
- function MyApp() {
35
- return (
36
- <PaymanChat
37
- config={{
38
- api: {
39
- baseUrl: "https://api.example.com",
40
- authToken: "your-token",
41
- streamEndpoint: "/api/playground/ask/stream", // Important!
42
- },
43
- workflowName: "my-workflow",
44
- userId: "user-123", // Required for chatStore and activeStreamStore
45
- workflowVersion: 1,
46
- stage: "DEV",
47
- sessionParams: {
48
- id: "user-123",
49
- name: "John Doe",
50
- },
51
- }}
52
- callbacks={{
53
- onError: (error) => console.error(error),
54
- }}
55
- />
56
- );
57
- }
58
16
  ```
59
17
 
60
- ### For Production
18
+ ## Minimal example
61
19
 
62
20
  ```tsx
63
21
  <PaymanChat
64
22
  config={{
65
23
  api: {
66
- baseUrl: "https://api.example.com",
67
- authToken: "your-api-key", // API key with stage configured
24
+ baseUrl: "https://api.paymanai.com",
25
+ headers: { Authorization: `Bearer ${token}` },
26
+ },
27
+ workflow: {
28
+ id: "wf_01H…", // optional; required for session history
29
+ name: "my-agent",
30
+ version: 3,
31
+ stage: "PROD",
68
32
  },
69
- workflowName: "my-workflow",
70
- userId: "user-123", // Required for chatStore and activeStreamStore
71
- stage: "PROD",
72
- sessionParams: {
73
- id: "user-123",
74
- name: "John Doe",
33
+ session: {
34
+ userId: "user-42", // client-side state-scope key
35
+ owner: { id: "user-42", label: "Alice" },
75
36
  },
37
+ ui: {
38
+ emptyState: { text: "How can I help?" },
39
+ input: {
40
+ placeholder: "Ask anything…",
41
+ voice: true,
42
+ },
43
+ sessionHistory: true,
44
+ },
45
+ }}
46
+ callbacks={{
47
+ onStreamComplete: (msg) => console.log(msg),
76
48
  }}
77
49
  />
78
50
  ```
79
51
 
80
- ## Custom Header
52
+ ## Configuration
81
53
 
82
- ```tsx
83
- import { PaymanChat, usePaymanChat } from "@paymanai/payman-ask-sdk";
54
+ The full config is a `BaseChatConfig` (from the core SDK) extended with `availability`, `ui`, and `observability`.
84
55
 
85
- function ChatHeader() {
86
- const chat = usePaymanChat();
87
-
88
- return (
89
- <div className="header">
90
- <h2>My Chat</h2>
91
- <button onClick={chat.resetSession}>Reset</button>
92
- <button onClick={chat.clearMessages}>Clear</button>
93
- </div>
94
- );
95
- }
56
+ ```ts
57
+ type ChatConfig = {
58
+ // ---- Core (shared with payman-typescript-ask-sdk) ------------------------
59
+ api: {
60
+ baseUrl: string;
61
+ apiKey?: string;
62
+ headers?: Record<string, string | undefined>;
63
+ streamEndpoint?: string; // default: "/api/workflows/ask/stream"
64
+ };
96
65
 
97
- function MyApp() {
98
- return (
99
- <PaymanChat config={config}>
100
- <ChatHeader />
101
- </PaymanChat>
102
- );
103
- }
104
- ```
66
+ workflow: {
67
+ id?: string; // workflow uuid; required when `ui.sessionHistory` is enabled
68
+ name: string;
69
+ version?: number;
70
+ stage?: "DEV" | "SBX" | "PROD";
71
+ };
105
72
 
106
- ## API Reference
107
-
108
- ### `config` (required)
109
-
110
- | Property | Type | Required | Description |
111
- |----------|------|----------|-------------|
112
- | `api` | `APIConfig` | ✅ | API configuration |
113
- | `workflowName` | `string` | ✅ | Workflow name |
114
- | `userId` | `string` | ✅ | User ID for chatStore and activeStreamStore (context store messages management) |
115
- | `workflowVersion` | `number` | | Workflow version (default: 1) |
116
- | `stage` | `WorkflowStage` | | Stage (DEV/SANDBOX/PROD) |
117
- | `sessionParams` | `SessionParams` | | User session info |
118
- | `autoGenerateSessionId` | `boolean` | | Auto-generate session ID |
119
- | `hasAskPermission` | `boolean` | | Show/hide input (default: true) |
120
- | `uiVersion` | `1 \| 2` | | Render original UI or v2 UI |
121
- | `showResetSession` | `boolean` | | Show a New Session button in the input bar with a confirmation modal before reset (default: false) |
122
- | `showAttachmentButton` | `boolean` | | Show/hide the v2 attachment (+) menu button (default: true) |
123
- | `showUploadImageButton` | `boolean` | | Show/hide the v2 Upload image option (default: true) |
124
- | `showAttachFileButton` | `boolean` | | Show/hide the v2 Attach file option (default: true) |
125
- | `enableVoice` | `boolean` | | Show/hide the voice input button in the composer (default: false) |
126
- | `voiceLang` | `string` | | Speech recognition language (default: `en-US`) |
127
- | `voiceInterimResults` | `boolean` | | Enable interim voice transcription updates (default: true) |
128
- | `voiceContinuous` | `boolean` | | Keep listening continuously while recording (default: true) |
129
- | `messageActions` | `MessageActionsConfig` | | Configure visible actions for `userMessageActions` and `assistantMessageActions` in the v2 UI |
130
-
131
- `messageActions` shape:
73
+ session?: {
74
+ userId?: string; // client-side state-scope key (NOT sent to API)
75
+ owner?: { id: string; label?: string };
76
+ autoGenerateId?: boolean; // default: true
77
+ initialId?: string;
78
+ initialMessages?: MessageDisplay[];
79
+ };
132
80
 
133
- ```ts
134
- messageActions: {
135
- userMessageActions?: {
136
- copy?: boolean;
137
- edit?: boolean;
138
- retry?: boolean;
81
+ // ---- React-only ----------------------------------------------------------
82
+ availability?:
83
+ | { state: "ready" }
84
+ | { state: "readOnly" }
85
+ | { state: "disabled"; reason?: React.ReactNode };
86
+
87
+ ui?: {
88
+ layout?: "centered" | "full-width";
89
+
90
+ agent?: { name?: string; showName?: boolean };
91
+
92
+ emptyState?: {
93
+ text?: string;
94
+ icon?: boolean;
95
+ content?: React.ReactNode;
96
+ };
97
+
98
+ input?: {
99
+ placeholder?: string;
100
+ showResetButton?: boolean;
101
+ attachments?: boolean | { uploadImage?: boolean; attachFile?: boolean };
102
+ voice?: boolean | { lang?: string; interimResults?: boolean; continuous?: boolean };
103
+ };
104
+
105
+ messages?: {
106
+ avatars?: boolean | { user?: boolean; assistant?: boolean };
107
+ timestamps?: boolean;
108
+ streamingDot?: boolean;
109
+ actions?: {
110
+ userMessageActions?: { copy?: boolean; edit?: boolean; retry?: boolean };
111
+ assistantMessageActions?: { copy?: boolean; trace?: boolean };
112
+ };
113
+ };
114
+
115
+ execution?: {
116
+ showSteps?: boolean;
117
+ completedLabel?: string; // default: "Completed in {time}s ({count} steps)"
118
+ streamingLabel?: string; // default: "View progress ({count} steps)"
119
+ };
120
+
121
+ /**
122
+ * `true` — enable with defaults.
123
+ * object — override width/collapse/page-size/persistKey.
124
+ */
125
+ sessionHistory?: boolean | {
126
+ defaultWidth?: number; // default: 280 px
127
+ minWidth?: number; // default: 240
128
+ maxWidth?: number; // default: 480
129
+ defaultCollapsed?: boolean; // desktop only; default: false
130
+ pageSize?: number; // default: 20
131
+ persistKey?: string; // default: `payman-chat-sidebar:${workflow.id}`
132
+ };
139
133
  };
140
- assistantMessageActions?: {
141
- copy?: boolean;
142
- trace?: boolean;
134
+
135
+ observability?: {
136
+ sentryDsn?: string;
143
137
  };
144
- }
138
+ };
145
139
  ```
146
140
 
147
- ### `APIConfig`
148
-
149
- | Property | Type | Required | Description |
150
- |----------|------|----------|-------------|
151
- | `baseUrl` | `string` | ✅ | API base URL |
152
- | `authToken` | `string` | | Auth token |
153
- | `headers` | `Record<string, string>` | | Custom headers |
154
- | `streamEndpoint` | `string` | | Stream endpoint path |
155
-
156
- ### `callbacks` (optional)
157
-
158
- | Callback | Type | Description |
159
- |----------|------|-------------|
160
- | `onSessionIdChange` | `(sessionId: string) => void` | Session ID changed |
161
- | `onError` | `(error: Error) => void` | Error occurred |
162
- | `onMessageSent` | `(message: MessageDisplay) => void` | Message sent |
163
- | `onStreamStart` | `() => void` | Stream started |
164
- | `onStreamComplete` | `(message: MessageDisplay) => void` | Stream completed |
165
- | `onExecutionTraceClick` | `(data: unknown) => void` | Trace button clicked |
166
- | `onResetSession` | `() => void` | New Session/reset button clicked |
167
- | `onUploadImageClick` | `() => void` | v2 Upload image option clicked |
168
- | `onAttachFileClick` | `() => void` | v2 Attach file option clicked |
169
-
170
- ### Context API: `usePaymanChat()`
171
-
172
- | Method | Type | Description |
173
- |--------|------|-------------|
174
- | `resetSession()` | `() => void` | Clear messages & reset session |
175
- | `clearMessages()` | `() => void` | Clear messages only |
176
- | `cancelStream()` | `() => void` | Cancel current stream |
177
- | `getSessionId()` | `() => string \| undefined` | Get session ID |
178
- | `getMessages()` | `() => MessageDisplay[]` | Get all messages |
179
- | `isWaitingForResponse` | `boolean` | Check if waiting |
180
-
181
- ## Documentation
182
-
183
- - **[USAGE.md](./USAGE.md)** - Comprehensive usage guide
184
- - **[CONTEXT_API.md](./CONTEXT_API.md)** - Context API reference
185
- - **[ENDPOINTS.md](./ENDPOINTS.md)** - API endpoints guide
186
- - **[CHANGELOG.md](./CHANGELOG.md)** - Version history
187
- - **[docs/](./docs/README.md)** - V2 streaming events, styling, and CSS class reference (`uiVersion: 2`)
188
-
189
- ## Theming: Shimmer (active step text)
190
-
191
- The active-step shimmer uses **full color values** only. Define these CSS variables in your app (e.g. in `:root` or your theme file) so the shimmer matches your theme:
192
-
193
- | Variable | Description |
194
- |----------|-------------|
195
- | `--payman-shimmer-muted` | Muted color (gradient ends) |
196
- | `--payman-shimmer-foreground` | Main text color (gradient sides) |
197
- | `--payman-shimmer-primary` | Accent color (gradient center) |
198
-
199
- **Example (hex theme):**
200
-
201
- ```css
202
- :root {
203
- --payman-shimmer-muted: var(--muted-foreground);
204
- --payman-shimmer-foreground: var(--foreground);
205
- --payman-shimmer-primary: var(--primary);
206
- }
207
- ```
141
+ ### Safe cosmetic defaults
208
142
 
209
- **Example (HSL-component theme):**
143
+ Leaving the `ui` block out renders a usable ChatGPT-style surface:
210
144
 
211
- ```css
212
- :root {
213
- --payman-shimmer-muted: hsl(var(--muted-foreground));
214
- --payman-shimmer-foreground: hsl(var(--foreground));
215
- --payman-shimmer-primary: hsl(var(--primary));
216
- }
217
- ```
145
+ - Layout: `full-width`
146
+ - Placeholder: `"Type your message..."`
147
+ - Empty-state text: `"What can I help with?"`
148
+ - Agent name: `"Assistant"` (shown)
149
+ - Streaming dot: on
150
+ - Execution steps: on
151
+ - No avatars, timestamps, or reset button
152
+ - No voice, no session history
218
153
 
219
- If these are not set, the widget falls back to neutral gray/blue.
154
+ Turn features on with booleans, and only reach for the full object form when you need custom labels, widths, or per-option toggles.
220
155
 
221
- ## Common Issues
156
+ ## Session history
222
157
 
223
- ### 401 Error: "Workflow stage is not set"
158
+ Pass `ui.sessionHistory: true` and provide `workflow.id` + `session.owner.id`. `<PaymanChat/>` mounts a resizable, collapsible sidebar on desktop and a hamburger-triggered drawer on mobile. Clicking a row calls `loadSession(sessionId)` — which cancels any in-flight stream, clears the current chat, fetches the conversation history, and renders it with `isHistorical: true` (renderers skip the thinking/step UI for those rows).
224
159
 
225
- Add `streamEndpoint` to your config:
160
+ Need custom chrome? Mount the sidebar yourself:
226
161
 
227
162
  ```tsx
228
- api: {
229
- baseUrl: "...",
230
- authToken: "...",
231
- streamEndpoint: "/api/playground/ask/stream", // Add this
163
+ import { SessionHistorySidebar, usePaymanChat } from "@paymanai/payman-ask-sdk";
164
+
165
+ function MyShell() {
166
+ const chat = usePaymanChat();
167
+ return (
168
+ <SessionHistorySidebar
169
+ config={config}
170
+ options={{ defaultWidth: 320 }}
171
+ onSelectSession={(s) => chat.loadSession(s.sessionId)}
172
+ mobileOpen={mobileOpen}
173
+ onMobileOpenChange={setMobileOpen}
174
+ />
175
+ );
232
176
  }
233
177
  ```
234
178
 
235
- See [ENDPOINTS.md](./ENDPOINTS.md) for details.
179
+ ## `usePaymanChat()` hook
236
180
 
237
- ## Examples
181
+ Call from any descendant of `<PaymanChat/>`:
238
182
 
239
- Check the integration examples:
240
- - `src/components/Playground/PlaygroundChatColumn/` - Playground integration
241
- - `src/components/Builder/ChatInterface/` - Builder integration
183
+ ```tsx
184
+ const chat = usePaymanChat();
185
+ chat.resetSession();
186
+ chat.loadSession(sessionId);
187
+ chat.cancelStream();
188
+ chat.getSessionId();
189
+ chat.getMessages();
190
+ ```
242
191
 
243
- ## License
192
+ ## Callbacks
244
193
 
245
- MIT
194
+ ```ts
195
+ type ChatCallbacks = {
196
+ onMessageSent?: (text: string) => void;
197
+ onStreamStart?: () => void;
198
+ onStreamComplete?: (message: MessageDisplay) => void;
199
+ onError?: (error: Error) => void;
200
+ onSessionIdChange?: (sessionId: string) => void;
201
+ onExecutionTraceClick?: (data: { message; tracingData?; executionId? }) => void;
202
+ onResetSession?: () => void;
203
+ onUploadImageClick?: () => void;
204
+ onAttachFileClick?: () => void;
205
+ onUserActionRequired?: (req: UserActionRequest) => void;
206
+ onUserActionEvent?: (eventType, message) => void;
207
+ };
208
+ ```
246
209
 
247
- ## Support
210
+ ## Migrating from v1
211
+
212
+ **The v2 release removes the old flat config and the `ui.engine = 1` path entirely.** The v1 renderer has been deleted. Translation table:
213
+
214
+ | v1 (flat) | v2 (nested) |
215
+ | ------------------------------- | ------------------------------------------------ |
216
+ | `api` | `api` (unchanged) |
217
+ | `workflowName` | `workflow.name` |
218
+ | `workflowVersion` | `workflow.version` |
219
+ | `stage` | `workflow.stage` |
220
+ | `sessionParams` | `session.owner` |
221
+ | `userId` | `session.userId` |
222
+ | `autoGenerateSessionId` | `session.autoGenerateId` |
223
+ | `initialSessionId` | `session.initialId` |
224
+ | `initialMessages` | `session.initialMessages` |
225
+ | `isChatDisabled` / `disabledComponent` / `hasAskPermission` | `availability: { state: "disabled" \| "readOnly" \| "ready", reason? }` |
226
+ | `sentryDsn` | `observability.sentryDsn` |
227
+ | `uiVersion` | **removed** (v2 only) |
228
+ | `enableVoice`, `voiceLang`, `voiceInterimResults`, `voiceContinuous` | `ui.input.voice: boolean \| VoiceOptions` |
229
+ | `placeholder` | `ui.input.placeholder` |
230
+ | `emptyStateText` / `showEmptyStateIcon` / `emptyStateComponent` | `ui.emptyState.{ text, icon, content }` |
231
+ | `showResetSession` | `ui.input.showResetButton` |
232
+ | `showAttachmentButton` / `showUploadImageButton` / `showAttachFileButton` | `ui.input.attachments: boolean \| { uploadImage, attachFile }` |
233
+ | `messageActions` | `ui.messages.actions` |
234
+ | `showAvatars` / `showUserAvatar` / `showAssistantAvatar` | `ui.messages.avatars: boolean \| { user, assistant }` |
235
+ | `showTimestamps` | `ui.messages.timestamps` |
236
+ | `showStreamingDot` | `ui.messages.streamingDot` |
237
+ | `showExecutionSteps` | `ui.execution.showSteps` |
238
+ | `streamingStepsText` | `ui.execution.streamingLabel` |
239
+ | `completedStepsText` | `ui.execution.completedLabel` |
240
+ | `showAgentName` / `agentName` | `ui.agent.{ showName, name }` |
241
+ | `inputStyle` / `animated` / `sidebarBrandName` / `disableInput` | **removed** (dead fields) |
242
+ | `showSessionParams` / header `onLoadSession` dropdown | **removed** — use `ui.sessionHistory` sidebar |
243
+
244
+ ### Deleted APIs
245
+
246
+ - `useChat` / `UseChatReturn` (v1). Use `useChatV2` / `UseChatV2Return`.
247
+ - `AgentMessage`, `MessageList`, `MessageRow`, `ChatInput`, `StreamingMessage`, `UserMessage`, `MessageRowSkeleton` component re-exports.
248
+ - `ChatConfig.uiVersion`.
249
+
250
+ ### New APIs
251
+
252
+ - `useChatV2().loadSession(sessionId)` — replace the active chat with history.
253
+ - `usePaymanChat().loadSession` — same, from context.
254
+ - `SessionHistorySidebar` component + `useSessionHistory` hook.
255
+ - `listSessions` / `listConversations` REST helpers (from the core SDK).
256
+ - `buildScopeKey(config)` — compose the client-side state-scope key from `session.userId + workflow.id + workflow.version + workflow.stage`.
257
+
258
+ ## React Native
259
+
260
+ v2 ships web-only for the moment. `PaymanChat` on React Native renders a placeholder — pin `@paymanai/payman-ask-sdk@^1` if you need the v1 native renderer while the v2 RN rewrite lands.
248
261
 
249
- For issues and questions, please file an issue on GitHub.
262
+ ## License
263
+
264
+ MIT