@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.
- package/README.md +104 -0
- package/dist/bundle.cjs.js +18 -30
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.es.js +3506 -7033
- package/dist/bundle.es.js.map +1 -1
- package/dist/bundle.iife.js +18 -30
- package/dist/bundle.iife.js.map +1 -1
- package/dist/bundle.umd.js +17 -29
- package/dist/bundle.umd.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/messages.d.ts +2 -0
- package/dist/messages.d.ts.map +1 -1
- package/dist/protocol/webrtc.d.ts.map +1 -1
- package/dist/protocol/websocket.d.ts.map +1 -1
- package/dist/runtime/context.d.ts +34 -0
- package/dist/runtime/context.d.ts.map +1 -0
- package/dist/runtime/handlers.d.ts +21 -0
- package/dist/runtime/handlers.d.ts.map +1 -0
- package/dist/runtime/listeners.d.ts +6 -0
- package/dist/runtime/listeners.d.ts.map +1 -0
- package/dist/runtime/protocols.d.ts +17 -0
- package/dist/runtime/protocols.d.ts.map +1 -0
- package/dist/runtime/threads.d.ts +35 -0
- package/dist/runtime/threads.d.ts.map +1 -0
- package/dist/runtime/utils.d.ts +10 -0
- package/dist/runtime/utils.d.ts.map +1 -0
- package/dist/runtime.d.ts +4 -22
- package/dist/runtime.d.ts.map +1 -1
- package/dist/storage/base.d.ts +19 -0
- package/dist/storage/base.d.ts.map +1 -0
- package/dist/storage/index.d.ts +3 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/persona.d.ts +30 -0
- package/dist/storage/persona.d.ts.map +1 -0
- package/dist/types.d.ts +51 -1
- package/dist/types.d.ts.map +1 -1
- package/package.json +16 -10
- package/playground/src/chat.tsx +51 -66
- package/playground/src/components/assistant-ui/thread-list.tsx +45 -12
- package/playground/src/components/assistant-ui/thread.tsx +34 -96
- package/playground/src/components/assistant-ui/threadlist-sidebar.tsx +59 -0
- package/playground/src/components/chat/logging.tsx +53 -0
- package/playground/src/components/ui/input.tsx +21 -0
- package/playground/src/components/ui/separator.tsx +26 -0
- package/playground/src/components/ui/sheet.tsx +139 -0
- package/playground/src/components/ui/sidebar.tsx +619 -0
- package/playground/src/components/ui/skeleton.tsx +13 -0
- package/playground/src/components/ui/tooltip.tsx +0 -2
- package/playground/src/hooks/theme.ts +70 -0
- package/playground/src/hooks/use-mobile.ts +19 -0
- package/src/index.ts +1 -0
- package/src/messages.ts +98 -8
- package/src/protocol/webrtc.ts +1 -0
- package/src/protocol/websocket.ts +5 -2
- package/src/runtime/context.ts +88 -0
- package/src/runtime/handlers.ts +276 -0
- package/src/runtime/index.ts +6 -0
- package/src/runtime/listeners.ts +79 -0
- package/src/runtime/protocols.ts +169 -0
- package/src/runtime/threads.ts +120 -0
- package/src/runtime/utils.ts +46 -0
- package/src/runtime.tsx +226 -326
- package/src/storage/base.ts +21 -0
- package/src/storage/index.ts +2 -0
- package/src/storage/persona.ts +132 -0
- package/src/types.ts +64 -2
- 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;
|
|
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:
|
|
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
|
},
|