@applica-software-guru/persona-sdk 0.1.83 → 0.1.85

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.
Files changed (68) hide show
  1. package/README.md +104 -0
  2. package/dist/bundle.cjs.js +18 -30
  3. package/dist/bundle.cjs.js.map +1 -1
  4. package/dist/bundle.es.js +3506 -7033
  5. package/dist/bundle.es.js.map +1 -1
  6. package/dist/bundle.iife.js +18 -30
  7. package/dist/bundle.iife.js.map +1 -1
  8. package/dist/bundle.umd.js +17 -29
  9. package/dist/bundle.umd.js.map +1 -1
  10. package/dist/index.d.ts +1 -0
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/messages.d.ts +2 -0
  13. package/dist/messages.d.ts.map +1 -1
  14. package/dist/protocol/webrtc.d.ts.map +1 -1
  15. package/dist/protocol/websocket.d.ts.map +1 -1
  16. package/dist/runtime/context.d.ts +34 -0
  17. package/dist/runtime/context.d.ts.map +1 -0
  18. package/dist/runtime/handlers.d.ts +21 -0
  19. package/dist/runtime/handlers.d.ts.map +1 -0
  20. package/dist/runtime/listeners.d.ts +6 -0
  21. package/dist/runtime/listeners.d.ts.map +1 -0
  22. package/dist/runtime/protocols.d.ts +17 -0
  23. package/dist/runtime/protocols.d.ts.map +1 -0
  24. package/dist/runtime/threads.d.ts +35 -0
  25. package/dist/runtime/threads.d.ts.map +1 -0
  26. package/dist/runtime/utils.d.ts +10 -0
  27. package/dist/runtime/utils.d.ts.map +1 -0
  28. package/dist/runtime.d.ts +4 -22
  29. package/dist/runtime.d.ts.map +1 -1
  30. package/dist/storage/base.d.ts +19 -0
  31. package/dist/storage/base.d.ts.map +1 -0
  32. package/dist/storage/index.d.ts +3 -0
  33. package/dist/storage/index.d.ts.map +1 -0
  34. package/dist/storage/persona.d.ts +30 -0
  35. package/dist/storage/persona.d.ts.map +1 -0
  36. package/dist/types.d.ts +51 -1
  37. package/dist/types.d.ts.map +1 -1
  38. package/package.json +16 -10
  39. package/playground/src/chat.tsx +51 -66
  40. package/playground/src/components/assistant-ui/thread-list.tsx +45 -12
  41. package/playground/src/components/assistant-ui/thread.tsx +34 -96
  42. package/playground/src/components/assistant-ui/threadlist-sidebar.tsx +59 -0
  43. package/playground/src/components/chat/logging.tsx +53 -0
  44. package/playground/src/components/ui/input.tsx +21 -0
  45. package/playground/src/components/ui/separator.tsx +26 -0
  46. package/playground/src/components/ui/sheet.tsx +139 -0
  47. package/playground/src/components/ui/sidebar.tsx +619 -0
  48. package/playground/src/components/ui/skeleton.tsx +13 -0
  49. package/playground/src/components/ui/tooltip.tsx +0 -2
  50. package/playground/src/hooks/theme.ts +70 -0
  51. package/playground/src/hooks/use-mobile.ts +19 -0
  52. package/src/index.ts +1 -0
  53. package/src/messages.ts +98 -8
  54. package/src/protocol/webrtc.ts +1 -0
  55. package/src/protocol/websocket.ts +5 -2
  56. package/src/runtime/context.ts +88 -0
  57. package/src/runtime/handlers.ts +276 -0
  58. package/src/runtime/index.ts +6 -0
  59. package/src/runtime/listeners.ts +79 -0
  60. package/src/runtime/protocols.ts +169 -0
  61. package/src/runtime/threads.ts +120 -0
  62. package/src/runtime/utils.ts +46 -0
  63. package/src/runtime.tsx +226 -326
  64. package/src/storage/base.ts +21 -0
  65. package/src/storage/index.ts +2 -0
  66. package/src/storage/persona.ts +132 -0
  67. package/src/types.ts +64 -2
  68. package/vite.config.ts +11 -1
@@ -0,0 +1,132 @@
1
+ import type { PersonaMessage, Session, ThreadData } from '../types';
2
+ import type { SessionStorage } from './base';
3
+ import type { PersonaLogger } from '../logging';
4
+
5
+ type PersonaSessionStorageOptions = {
6
+ endpoint: string;
7
+ apiKey?: string;
8
+ pageSize?: number;
9
+ logger?: PersonaLogger;
10
+ };
11
+
12
+ export class PersonaSessionStorage implements SessionStorage {
13
+ private endpoint: string;
14
+ private apiKey?: string;
15
+ private pageSize: number;
16
+ private logger?: PersonaLogger;
17
+
18
+ constructor(opts: PersonaSessionStorageOptions) {
19
+ this.endpoint = opts.endpoint.replace(/\/$/, '');
20
+ this.apiKey = opts.apiKey;
21
+ this.pageSize = opts.pageSize ?? 200;
22
+ this.logger = opts.logger;
23
+ }
24
+
25
+ private buildHeaders() {
26
+ const headers: Record<string, string> = { 'Content-Type': 'application/json' };
27
+ if (this.apiKey) headers['x-persona-apikey'] = this.apiKey;
28
+ return headers;
29
+ }
30
+
31
+ /**
32
+ * Fetch messages for a session from the Persona REST API
33
+ */
34
+ async sync(sessionId: Session): Promise<PersonaMessage[]> {
35
+ if (!sessionId) return [];
36
+ const url = `${this.endpoint}/sessions/${encodeURIComponent(String(sessionId))}/messages?page=1&size=${this.pageSize}`;
37
+
38
+ try {
39
+ const res = await fetch(url, { method: 'GET', headers: this.buildHeaders() });
40
+ if (!res.ok) {
41
+ // Log and return empty list on error
42
+ this.logger?.warn('PersonaSessionStorage: failed to fetch messages', res.status, await res.text());
43
+ return [];
44
+ }
45
+
46
+ const data = await res.json();
47
+ if (!Array.isArray(data.items)) return [];
48
+
49
+ // Try to normalize createdAt strings to Date objects
50
+ const messages: PersonaMessage[] = data.items.map((m: any) => {
51
+ const msg: PersonaMessage = {
52
+ id: m.id ?? m.messageId ?? undefined,
53
+ protocol: m.protocol,
54
+ thought: m.thought,
55
+ text: m.text ?? '',
56
+ image: m.image,
57
+ type: m.type ?? 'text',
58
+ role: m.role ?? 'assistant',
59
+ file: m.file,
60
+ sources: m.sources,
61
+ sessionId: m.sessionId ?? sessionId,
62
+ finishReason: m.finishReason,
63
+ functionCalls: m.functionCalls,
64
+ functionResponse: m.functionResponse,
65
+ status: m.status,
66
+ createdAt: m.createdAt ? new Date(m.createdAt) : undefined,
67
+ metadata: m.metadata,
68
+ };
69
+ return msg;
70
+ });
71
+
72
+ return messages;
73
+ } catch (err) {
74
+ // Network or parsing error
75
+ this.logger?.warn('PersonaSessionStorage: error fetching messages', err);
76
+ return [];
77
+ }
78
+ }
79
+
80
+ async remove(sessionId: Session): Promise<void> {
81
+ if (!sessionId) return;
82
+ const url = `${this.endpoint}/sessions/${encodeURIComponent(String(sessionId))}`;
83
+ try {
84
+ const res = await fetch(url, { method: 'DELETE', headers: this.buildHeaders() });
85
+ if (!res.ok) {
86
+ const text = await res.text();
87
+ this.logger?.warn('PersonaSessionStorage: failed to delete session', res.status, text);
88
+ throw new Error(`Failed to delete session: ${res.status}`);
89
+ }
90
+ return;
91
+ } catch (err) {
92
+ this.logger?.warn('PersonaSessionStorage: error deleting session', err);
93
+ throw err;
94
+ }
95
+ }
96
+
97
+ async clearAll(): Promise<void> {
98
+ return Promise.reject(new Error('PersonaAPIMessageStorage: clearAll not supported'));
99
+ }
100
+
101
+ /**
102
+ * List all threads for a specific user from the Persona REST API
103
+ * GET /sessions?userId={userId}&page=1&size=100
104
+ */
105
+ async list(agentId: string, userId?: string): Promise<ThreadData[]> {
106
+ const params = new URLSearchParams({ page: '1', size: '100' });
107
+ if (userId) params.set('userId', userId);
108
+ if (agentId) params.set('agentId', agentId);
109
+
110
+ const url = `${this.endpoint}/sessions?${params.toString()}`;
111
+ try {
112
+ const res = await fetch(url, { method: 'GET', headers: this.buildHeaders() });
113
+ if (!res.ok) {
114
+ this.logger?.warn('PersonaSessionStorage: failed to list sessions', res.status);
115
+ return [];
116
+ }
117
+
118
+ const data = await res.json();
119
+ if (!Array.isArray(data.items)) return [];
120
+ const threads: import('../types').ThreadData[] = data.items.map((item: any) => ({
121
+ threadId: item.code || item.id,
122
+ title: item.title || `Session ${item.code || item.id}`,
123
+ status: item.status === 'archived' ? 'archived' : 'regular',
124
+ }));
125
+
126
+ return threads;
127
+ } catch (err) {
128
+ this.logger?.warn('PersonaSessionStorage: error listing sessions', err);
129
+ return [];
130
+ }
131
+ }
132
+ }
package/src/types.ts CHANGED
@@ -1,7 +1,10 @@
1
1
  import { PersonaTools } from 'src/protocol';
2
- import { PersonaLogger } from './logging';
3
2
  import { ReactNode } from 'react';
4
3
  import type { ToolInstance } from './tools';
4
+ import type { PersonaLogger } from './logging';
5
+ import type { SessionStorage } from './storage';
6
+
7
+ export type { PersonaLogger, SessionStorage };
5
8
 
6
9
  export type ReadonlyJSONObject = {
7
10
  readonly [key: string]: string | number | boolean | null | ReadonlyJSONObject | ReadonlyArray<ReadonlyJSONObject>;
@@ -97,7 +100,7 @@ export type PersonaMessage = {
97
100
  id?: string | null;
98
101
  protocol?: string;
99
102
  thought?: string;
100
- text: string; //todo: puo essere null
103
+ text: string;
101
104
  image?: PersonaImage;
102
105
  type: 'reasoning' | 'text' | 'transaction' | 'command';
103
106
  role: 'user' | 'assistant' | 'function';
@@ -108,6 +111,12 @@ export type PersonaMessage = {
108
111
  functionCalls?: FunctionCall[];
109
112
  functionResponse?: FunctionResponse;
110
113
  status?: { type: 'running' | 'complete' | 'incomplete' };
114
+ // ThreadMessageLike compatible fields
115
+ createdAt?: Date;
116
+ metadata?: {
117
+ custom?: Record<string, unknown>;
118
+ [key: string]: unknown;
119
+ };
111
120
  };
112
121
 
113
122
  export type ModelResponse = {
@@ -133,6 +142,12 @@ export type Session = string | null | undefined;
133
142
 
134
143
  export type TransformMessages = (messages: PersonaMessage[]) => PersonaMessage[];
135
144
 
145
+ export type ThreadData = {
146
+ threadId: string;
147
+ title?: string;
148
+ status: 'regular' | 'archived';
149
+ };
150
+
136
151
  export type MessageListenerCallback = (message: PersonaPacket) => void;
137
152
  export type StatusChangeCallback = (status: ProtocolStatus) => void;
138
153
 
@@ -142,6 +157,7 @@ export type PersonaProtocolBaseConfig = {
142
157
  logger?: PersonaLogger;
143
158
  apiKey: string;
144
159
  agentId: string;
160
+ userId?: string;
145
161
  };
146
162
 
147
163
  export interface PersonaProtocol {
@@ -195,4 +211,50 @@ export type PersonaConfig = PersonaBaseConfig &
195
211
  * Optional message transform function that processes messages before they are displayed
196
212
  */
197
213
  transformMessages?: TransformMessages;
214
+
215
+ /**
216
+ * Enable thread management support
217
+ */
218
+ enableThreads?: boolean;
219
+
220
+ /**
221
+ * Session storage implementation
222
+ * If not provided, defaults to PersonaSessionStorage
223
+ */
224
+ sessionStorage?: SessionStorage;
225
+
226
+ /**
227
+ * Initial thread list (if thread management is enabled)
228
+ */
229
+ initialThreads?: ThreadData[];
230
+
231
+ /**
232
+ * Callback when a new thread is created
233
+ */
234
+ onThreadCreate?: (threadId: string) => void;
235
+
236
+ /**
237
+ * Callback when switching to a thread
238
+ */
239
+ onThreadSwitch?: (threadId: string) => void;
240
+
241
+ /**
242
+ * Callback when a thread is renamed
243
+ */
244
+ onThreadRename?: (threadId: string, newTitle: string) => void;
245
+
246
+ /**
247
+ * Callback when a thread is archived
248
+ */
249
+ onThreadArchive?: (threadId: string) => void;
250
+
251
+ /**
252
+ * Callback when a thread is unarchived
253
+ */
254
+ onThreadUnarchive?: (threadId: string) => void;
255
+
256
+ /**
257
+ * Callback when a thread is deleted
258
+ */
259
+ onThreadDelete?: (threadId: string) => void;
198
260
  };
package/vite.config.ts CHANGED
@@ -18,7 +18,13 @@ export default defineConfig((configEnv: ConfigEnv) => {
18
18
  fileName: (format: string) => `bundle.${format}.js`,
19
19
  },
20
20
  rollupOptions: {
21
- external: Object.keys(packageJson.peerDependencies),
21
+ external: [
22
+ ...Object.keys(packageJson.peerDependencies),
23
+ ...Object.keys(packageJson.dependencies || {}),
24
+ /^react\//,
25
+ /^react-dom\//,
26
+ /^@radix-ui\//,
27
+ ],
22
28
  input: resolve(__dirname, 'src', 'index.ts'),
23
29
  output: {
24
30
  globals: {
@@ -27,6 +33,10 @@ export default defineConfig((configEnv: ConfigEnv) => {
27
33
  'react/jsx-runtime': 'React',
28
34
  'react/jsx-dev-runtime': 'React',
29
35
  '@assistant-ui/react': 'AssistantUI',
36
+ '@radix-ui/react-dialog': 'RadixDialog',
37
+ '@radix-ui/react-slot': 'RadixSlot',
38
+ 'rehype-raw': 'rehypeRaw',
39
+ zustand: 'zustand',
30
40
  },
31
41
  },
32
42
  },