@applica-software-guru/persona-sdk 0.1.46 → 0.1.48
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 +217 -0
- package/dist/bundle.cjs.js +2 -2
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.es.js +304 -187
- package/dist/bundle.es.js.map +1 -1
- package/dist/bundle.iife.js +2 -2
- package/dist/bundle.iife.js.map +1 -1
- package/dist/bundle.umd.js +2 -2
- package/dist/bundle.umd.js.map +1 -1
- package/dist/messages.d.ts.map +1 -1
- package/dist/protocol/base.d.ts +4 -3
- package/dist/protocol/base.d.ts.map +1 -1
- package/dist/protocol/index.d.ts +1 -0
- package/dist/protocol/index.d.ts.map +1 -1
- package/dist/protocol/rest.d.ts.map +1 -1
- package/dist/protocol/transaction.d.ts +50 -0
- package/dist/protocol/transaction.d.ts.map +1 -0
- package/dist/protocol/webrtc.d.ts.map +1 -1
- package/dist/protocol/websocket.d.ts.map +1 -1
- package/dist/runtime.d.ts.map +1 -1
- package/dist/types.d.ts +36 -2
- package/dist/types.d.ts.map +1 -1
- package/package.json +3 -3
- package/playground/src/chat.tsx +10 -1
- package/src/messages.ts +3 -0
- package/src/protocol/base.ts +14 -3
- package/src/protocol/index.ts +1 -0
- package/src/protocol/rest.ts +6 -1
- package/src/protocol/transaction.ts +154 -0
- package/src/protocol/webrtc.ts +3 -6
- package/src/protocol/websocket.ts +3 -9
- package/src/runtime.tsx +28 -3
- package/src/types.ts +42 -2
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { PersonaProtocolBase } from './base';
|
|
2
|
+
import {
|
|
3
|
+
Message,
|
|
4
|
+
Session,
|
|
5
|
+
ProtocolStatus,
|
|
6
|
+
PersonaProtocolBaseConfig,
|
|
7
|
+
PersonaTransaction,
|
|
8
|
+
FunctionCall,
|
|
9
|
+
ReadonlyJSONObject,
|
|
10
|
+
} from '../types';
|
|
11
|
+
|
|
12
|
+
type FinishTransactionRequest = {
|
|
13
|
+
success: boolean;
|
|
14
|
+
output: any;
|
|
15
|
+
error: string | null;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
class PersonaTransactionsManager {
|
|
19
|
+
private config: PersonaTransactionProtocolConfig;
|
|
20
|
+
|
|
21
|
+
constructor(config: PersonaTransactionProtocolConfig) {
|
|
22
|
+
this.config = config;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async complete(transaction: PersonaTransaction, request: FinishTransactionRequest): Promise<void> {
|
|
26
|
+
await this.persist(transaction, { ...request, success: true });
|
|
27
|
+
this.config.logger?.debug('Transaction completed:', transaction);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async fail(transaction: PersonaTransaction, request: FinishTransactionRequest): Promise<void> {
|
|
31
|
+
await this.persist(transaction, { ...request, success: false });
|
|
32
|
+
this.config.logger?.debug('Transaction failed:', { ...transaction, ...request });
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async persist(transaction: PersonaTransaction, request: FinishTransactionRequest): Promise<void> {
|
|
36
|
+
await fetch(`${this.config.apiUrl}/transactions/${transaction.id}`, {
|
|
37
|
+
body: JSON.stringify(request),
|
|
38
|
+
method: 'POST',
|
|
39
|
+
headers: {
|
|
40
|
+
'Content-Type': 'application/json',
|
|
41
|
+
Accept: 'application/json',
|
|
42
|
+
'x-persona-apikey': this.config.apiKey,
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export type PersonaToolCallback = (args: ReadonlyJSONObject | undefined) => void;
|
|
49
|
+
export type PersonaTools = {
|
|
50
|
+
[key: string]: PersonaToolCallback;
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
class PersonaPersistableTransaction {
|
|
54
|
+
private transaction: PersonaTransaction;
|
|
55
|
+
private manager: PersonaTransactionsManager;
|
|
56
|
+
|
|
57
|
+
constructor(transaction: PersonaTransaction, manager: PersonaTransactionsManager) {
|
|
58
|
+
this.transaction = transaction;
|
|
59
|
+
this.manager = manager;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
public getFunctionCall(): FunctionCall | null {
|
|
63
|
+
return this.transaction.functionCall;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async invoke(tools: PersonaTools): Promise<void> {
|
|
67
|
+
const functionCall = this.transaction.functionCall;
|
|
68
|
+
if (!functionCall) {
|
|
69
|
+
await this.fail('No function call found');
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
const functionName = functionCall.name;
|
|
73
|
+
const functionArgs = functionCall.args;
|
|
74
|
+
const tool = tools[functionName];
|
|
75
|
+
if (!tool) {
|
|
76
|
+
await this.fail(`Tool ${functionName} not found`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
try {
|
|
80
|
+
const result = await tool(functionArgs);
|
|
81
|
+
await this.complete({ date: new Date().toISOString(), result });
|
|
82
|
+
} catch (error) {
|
|
83
|
+
await this.fail(`Error executing tool ${functionName}: ${error}`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
async complete(output: any): Promise<void> {
|
|
87
|
+
await this.manager.complete(this.transaction, { success: true, output, error: null });
|
|
88
|
+
}
|
|
89
|
+
async fail(error: string): Promise<void> {
|
|
90
|
+
await this.manager.fail(this.transaction, { success: false, output: null, error });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
type PersonaTransactionCallback = (transaction: PersonaPersistableTransaction) => void;
|
|
95
|
+
|
|
96
|
+
type PersonaTransactionProtocolConfig = PersonaProtocolBaseConfig & {
|
|
97
|
+
apiUrl: string;
|
|
98
|
+
onTransaction: PersonaTransactionCallback;
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
class PersonaTransactionProtocol extends PersonaProtocolBase {
|
|
102
|
+
status: ProtocolStatus;
|
|
103
|
+
autostart: boolean;
|
|
104
|
+
session: Session;
|
|
105
|
+
config: PersonaTransactionProtocolConfig;
|
|
106
|
+
notify: boolean = true;
|
|
107
|
+
|
|
108
|
+
constructor(config: PersonaTransactionProtocolConfig) {
|
|
109
|
+
super();
|
|
110
|
+
this.config = config;
|
|
111
|
+
this.status = 'disconnected';
|
|
112
|
+
this.autostart = true;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
public getName(): string {
|
|
116
|
+
return 'transaction';
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
public getPriority(): number {
|
|
120
|
+
return 0;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public async connect(session: Session): Promise<Session> {
|
|
124
|
+
this.setStatus('connected');
|
|
125
|
+
return session;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public async disconnect(): Promise<void> {
|
|
129
|
+
this.setStatus('disconnected');
|
|
130
|
+
this.session = null;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
public async syncSession(session: Session): Promise<void> {
|
|
134
|
+
this.session = session;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
public async send(message: Message): Promise<void> {
|
|
138
|
+
this.config.logger?.debug('Sending message:', message);
|
|
139
|
+
throw new Error('Not implemented');
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
public onTransaction(transaction: PersonaTransaction): void {
|
|
143
|
+
if (!this.config.onTransaction) {
|
|
144
|
+
this.config.logger?.error('Transaction protocol config is not set');
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const manager = new PersonaTransactionsManager(this.config);
|
|
148
|
+
const persistable = new PersonaPersistableTransaction(transaction, manager);
|
|
149
|
+
this.config.onTransaction(persistable);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
export { PersonaTransactionProtocol };
|
|
154
|
+
export type { PersonaTransactionProtocolConfig, FinishTransactionRequest, PersonaPersistableTransaction, PersonaTransactionCallback };
|
package/src/protocol/webrtc.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PersonaProtocolBase } from './base';
|
|
2
|
-
import { Message,
|
|
2
|
+
import { Message, PersonaPayload, PersonaProtocolBaseConfig, ProtocolStatus, Session } from '../types';
|
|
3
3
|
|
|
4
4
|
type AudioAnalysisData = {
|
|
5
5
|
localAmplitude: number;
|
|
@@ -274,11 +274,8 @@ class PersonaWebRTCProtocol extends PersonaProtocolBase {
|
|
|
274
274
|
this.autostart = config?.autostart ?? false;
|
|
275
275
|
this.webRTCClient = new PersonaWebRTCClient(config);
|
|
276
276
|
this.webRTCClient.addMessageCallback((msg: MessageEvent) => {
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
if (data.type === 'message') {
|
|
280
|
-
this.notifyMessage(data.payload as PersonaMessage);
|
|
281
|
-
}
|
|
277
|
+
const data = JSON.parse(msg.data) as PersonaPayload;
|
|
278
|
+
this.notifyMessage(data);
|
|
282
279
|
});
|
|
283
280
|
}
|
|
284
281
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Message,
|
|
1
|
+
import { Message, PersonaPayload, PersonaProtocolBaseConfig, ProtocolStatus, Session } from '../types';
|
|
2
2
|
import { PersonaProtocolBase } from './base';
|
|
3
3
|
|
|
4
4
|
type PersonaWebSocketProtocolConfig = PersonaProtocolBaseConfig & {
|
|
@@ -56,14 +56,8 @@ class PersonaWebSocketProtocol extends PersonaProtocolBase {
|
|
|
56
56
|
this.setStatus('connected');
|
|
57
57
|
});
|
|
58
58
|
this.webSocket.addEventListener('message', (event) => {
|
|
59
|
-
const data = JSON.parse(event.data) as
|
|
60
|
-
|
|
61
|
-
if (data.type !== 'message') {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const message = data.payload as PersonaMessage & { thought?: string };
|
|
65
|
-
|
|
66
|
-
this.notifyMessage(message?.thought ? { role: 'assistant', type: 'reasoning', text: message.thought } : message);
|
|
59
|
+
const data = JSON.parse(event.data) as PersonaPayload;
|
|
60
|
+
this.notifyMessage(data);
|
|
67
61
|
});
|
|
68
62
|
this.webSocket.addEventListener('close', () => {
|
|
69
63
|
this.setStatus('disconnected');
|
package/src/runtime.tsx
CHANGED
|
@@ -3,16 +3,20 @@ import { useExternalStoreRuntime, AppendMessage, AssistantRuntimeProvider } from
|
|
|
3
3
|
import {
|
|
4
4
|
PersonaConfig,
|
|
5
5
|
PersonaMessage,
|
|
6
|
+
PersonaPayload,
|
|
6
7
|
PersonaProtocol,
|
|
7
8
|
PersonaProtocolBaseConfig,
|
|
8
9
|
PersonaResponse,
|
|
10
|
+
PersonaTransaction,
|
|
9
11
|
ProtocolStatus,
|
|
10
12
|
Session,
|
|
11
13
|
} from './types';
|
|
12
14
|
import { parseMessages, convertMessage } from './messages';
|
|
13
15
|
import {
|
|
16
|
+
PersonaPersistableTransaction,
|
|
14
17
|
PersonaRESTProtocol,
|
|
15
18
|
PersonaRESTProtocolConfig,
|
|
19
|
+
PersonaTransactionProtocol,
|
|
16
20
|
PersonaWebRTCProtocol,
|
|
17
21
|
PersonaWebRTCProtocolConfig,
|
|
18
22
|
PersonaWebSocketProtocol,
|
|
@@ -49,7 +53,7 @@ function PersonaRuntimeProviderInner({
|
|
|
49
53
|
const baseEndpoint = dev ? 'localhost:8000' : 'persona.applica.guru/api';
|
|
50
54
|
const baseEndpointProtocol = dev ? 'http' : 'https';
|
|
51
55
|
const baseWebSocketProtocol = dev ? 'ws' : 'wss';
|
|
52
|
-
|
|
56
|
+
let availableProtocols = Object.keys(_protocols).map((key) => {
|
|
53
57
|
switch (key) {
|
|
54
58
|
case 'rest':
|
|
55
59
|
const restConfig: PersonaProtocolBaseConfig | true | undefined = _protocols[key];
|
|
@@ -88,6 +92,20 @@ function PersonaRuntimeProviderInner({
|
|
|
88
92
|
throw new Error(`Unknown protocol: ${key}`);
|
|
89
93
|
}
|
|
90
94
|
});
|
|
95
|
+
|
|
96
|
+
if (config.tools) {
|
|
97
|
+
availableProtocols.push(
|
|
98
|
+
new PersonaTransactionProtocol({
|
|
99
|
+
apiUrl: `${baseEndpointProtocol}://${baseEndpoint}`,
|
|
100
|
+
apiKey: config.apiKey,
|
|
101
|
+
agentId: config.agentId,
|
|
102
|
+
onTransaction: async (transaction: PersonaPersistableTransaction) => {
|
|
103
|
+
await transaction.invoke(config.tools!);
|
|
104
|
+
},
|
|
105
|
+
logger,
|
|
106
|
+
}),
|
|
107
|
+
);
|
|
108
|
+
}
|
|
91
109
|
return availableProtocols;
|
|
92
110
|
}
|
|
93
111
|
throw new Error('Invalid protocols configuration');
|
|
@@ -109,8 +127,15 @@ function PersonaRuntimeProviderInner({
|
|
|
109
127
|
protocolsStatus.set(protocol.getName(), status);
|
|
110
128
|
setProtocolsStatus(new Map(protocolsStatus));
|
|
111
129
|
});
|
|
112
|
-
protocol.addMessageListener((message:
|
|
113
|
-
|
|
130
|
+
protocol.addMessageListener((message: PersonaPayload) => {
|
|
131
|
+
if (message.type === 'message') {
|
|
132
|
+
const personaMessage = message.payload as PersonaMessage;
|
|
133
|
+
setMessages((currentConversation) =>
|
|
134
|
+
parseMessages([...currentConversation, ...[{ ...personaMessage, protocol: protocol.getName() }]]),
|
|
135
|
+
);
|
|
136
|
+
} else if (message.type === 'transaction') {
|
|
137
|
+
protocols.filter((p) => p !== protocol).forEach((p) => p.onTransaction(message.payload as PersonaTransaction));
|
|
138
|
+
}
|
|
114
139
|
});
|
|
115
140
|
if (protocol.autostart && protocol.status === 'disconnected') {
|
|
116
141
|
logger?.debug(`Connecting to protocol: ${protocol.getName()}`);
|
package/src/types.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { PersonaTools } from 'src/protocol';
|
|
1
2
|
import { PersonaLogger } from './logging';
|
|
2
3
|
import { ReactNode } from 'react';
|
|
3
4
|
|
|
@@ -23,11 +24,41 @@ export type PersonaFile = {
|
|
|
23
24
|
contentType: string;
|
|
24
25
|
};
|
|
25
26
|
|
|
27
|
+
export type PersonaSession = {
|
|
28
|
+
id: string;
|
|
29
|
+
code: string;
|
|
30
|
+
projectId: string;
|
|
31
|
+
agentId: string;
|
|
32
|
+
currentAgentId: string;
|
|
33
|
+
userId: string;
|
|
34
|
+
status: 'active' | 'finished';
|
|
35
|
+
type: 'realtime' | 'async';
|
|
36
|
+
createdAt: string;
|
|
37
|
+
finishedAt: string | null;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export type PersonaAgentContext = {
|
|
41
|
+
data: unknown;
|
|
42
|
+
files: PersonaFile[];
|
|
43
|
+
session: PersonaSession;
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
export type PersonaTransaction = {
|
|
47
|
+
id: string;
|
|
48
|
+
projectId: string;
|
|
49
|
+
sessionId: string;
|
|
50
|
+
status: 'pending' | 'completed' | 'failed';
|
|
51
|
+
error: string | null;
|
|
52
|
+
functionCall: FunctionCall | null;
|
|
53
|
+
context: PersonaAgentContext;
|
|
54
|
+
};
|
|
55
|
+
|
|
26
56
|
export type PersonaMessage = {
|
|
27
57
|
id?: string | null;
|
|
28
58
|
protocol?: string;
|
|
59
|
+
thought?: string;
|
|
29
60
|
text: string;
|
|
30
|
-
type: 'reasoning' | 'text';
|
|
61
|
+
type: 'reasoning' | 'text' | 'transaction';
|
|
31
62
|
role: 'user' | 'assistant' | 'function';
|
|
32
63
|
files?: PersonaFile[];
|
|
33
64
|
sessionId?: string;
|
|
@@ -36,6 +67,11 @@ export type PersonaMessage = {
|
|
|
36
67
|
functionResponse?: FunctionResponse;
|
|
37
68
|
};
|
|
38
69
|
|
|
70
|
+
export type PersonaPayload = {
|
|
71
|
+
type: 'message' | 'transaction';
|
|
72
|
+
payload: PersonaMessage | PersonaTransaction;
|
|
73
|
+
};
|
|
74
|
+
|
|
39
75
|
export type ModelResponse = {
|
|
40
76
|
messages: PersonaMessage[];
|
|
41
77
|
};
|
|
@@ -58,7 +94,7 @@ export type PersonaWebRTCConfig = PersonaBaseConfig & {
|
|
|
58
94
|
export type Session = string | null | undefined;
|
|
59
95
|
export type Message = string;
|
|
60
96
|
|
|
61
|
-
export type MessageListenerCallback = (message:
|
|
97
|
+
export type MessageListenerCallback = (message: PersonaPayload) => void;
|
|
62
98
|
export type StatusChangeCallback = (status: ProtocolStatus) => void;
|
|
63
99
|
|
|
64
100
|
export type ProtocolStatus = 'disconnected' | 'connecting' | 'connected';
|
|
@@ -78,6 +114,8 @@ export interface PersonaProtocol {
|
|
|
78
114
|
connect: (session?: Session) => Promise<Session>;
|
|
79
115
|
disconnect: () => Promise<void>;
|
|
80
116
|
|
|
117
|
+
onTransaction: (transaction: PersonaTransaction) => void;
|
|
118
|
+
|
|
81
119
|
setSession: (session: Session) => Promise<void>;
|
|
82
120
|
|
|
83
121
|
send: (message: Message) => Promise<void>;
|
|
@@ -102,4 +140,6 @@ export type PersonaConfig = PersonaBaseConfig &
|
|
|
102
140
|
webrtc?: PersonaProtocolBaseConfig | true;
|
|
103
141
|
websocket?: PersonaProtocolBaseConfig | true;
|
|
104
142
|
};
|
|
143
|
+
|
|
144
|
+
tools?: PersonaTools;
|
|
105
145
|
};
|