@applica-software-guru/persona-sdk 0.1.100 → 0.1.101
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/.eslintrc.cjs +6 -5
- package/.nvmrc +1 -1
- package/.prettierignore +3 -5
- package/.prettierrc +3 -5
- package/README.md +360 -20
- package/bitbucket-pipelines.yml +6 -5
- package/dist/bundle.cjs.js +1 -27
- package/dist/bundle.cjs.js.map +1 -1
- package/dist/bundle.es.js +700 -5086
- package/dist/bundle.es.js.map +1 -1
- package/dist/index.d.ts +1442 -8
- package/package.json +9 -51
- package/src/agents/agents-api.ts +66 -0
- package/src/agents/types.ts +349 -0
- package/src/auth/api-key-auth.ts +13 -0
- package/src/auth/authentication-provider.ts +4 -0
- package/src/auth/bearer-token-auth.ts +13 -0
- package/src/auth/index.ts +3 -0
- package/src/billing/billing-client.ts +182 -0
- package/src/billing/types.ts +166 -0
- package/src/credentials/credentials-api.ts +40 -0
- package/src/credentials/types.ts +67 -0
- package/src/exceptions.ts +10 -0
- package/src/features/feature-templates-api.ts +43 -0
- package/src/features/features-api.ts +16 -0
- package/src/features/types.ts +25 -0
- package/src/http-api.ts +102 -0
- package/src/index.ts +179 -7
- package/src/knowledges/knowledge-base-documents-api.ts +39 -0
- package/src/knowledges/knowledge-bases-api.ts +48 -0
- package/src/knowledges/types.ts +70 -0
- package/src/known-models/known-models-api.ts +33 -0
- package/src/known-models/types.ts +7 -0
- package/src/missions/missions-api.ts +62 -0
- package/src/missions/types.ts +25 -0
- package/src/paginated.ts +6 -0
- package/src/persona-sdk.ts +104 -0
- package/src/projects/projects-api.ts +90 -0
- package/src/projects/types.ts +52 -0
- package/src/revisions/types.ts +9 -0
- package/src/service-prices/service-prices-api.ts +33 -0
- package/src/service-prices/types.ts +8 -0
- package/src/sessions/sessions-api.ts +90 -0
- package/src/sessions/types.ts +150 -0
- package/src/triggers/trigger-executions-api.ts +28 -0
- package/src/triggers/triggers-api.ts +38 -0
- package/src/triggers/types.ts +50 -0
- package/src/values/values-api.ts +84 -0
- package/src/workflows/types.ts +150 -0
- package/src/workflows/workflow-executions-api.ts +28 -0
- package/src/workflows/workflows-api.ts +52 -0
- package/tsconfig.json +20 -28
- package/vite.config.ts +20 -67
- package/.github/copilot-instructions.md +0 -3
- package/CLAUDE.md +0 -3
- package/GEMINI.md +0 -3
- package/components.json +0 -24
- package/dist/bundle.iife.js +0 -28
- package/dist/bundle.iife.js.map +0 -1
- package/dist/bundle.umd.js +0 -28
- package/dist/bundle.umd.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/logging.d.ts +0 -18
- package/dist/logging.d.ts.map +0 -1
- package/dist/messages.d.ts +0 -9
- package/dist/messages.d.ts.map +0 -1
- package/dist/projects.d.ts +0 -17
- package/dist/projects.d.ts.map +0 -1
- package/dist/protocol/base.d.ts +0 -25
- package/dist/protocol/base.d.ts.map +0 -1
- package/dist/protocol/index.d.ts +0 -6
- package/dist/protocol/index.d.ts.map +0 -1
- package/dist/protocol/rest.d.ts +0 -25
- package/dist/protocol/rest.d.ts.map +0 -1
- package/dist/protocol/transaction.d.ts +0 -56
- package/dist/protocol/transaction.d.ts.map +0 -1
- package/dist/protocol/webrtc.d.ts +0 -60
- package/dist/protocol/webrtc.d.ts.map +0 -1
- package/dist/protocol/websocket.d.ts +0 -22
- package/dist/protocol/websocket.d.ts.map +0 -1
- package/dist/runtime/context.d.ts +0 -34
- package/dist/runtime/context.d.ts.map +0 -1
- package/dist/runtime/file-attachment-adapter.d.ts +0 -15
- package/dist/runtime/file-attachment-adapter.d.ts.map +0 -1
- package/dist/runtime/handlers.d.ts +0 -21
- package/dist/runtime/handlers.d.ts.map +0 -1
- package/dist/runtime/listeners.d.ts +0 -6
- package/dist/runtime/listeners.d.ts.map +0 -1
- package/dist/runtime/protocols.d.ts +0 -17
- package/dist/runtime/protocols.d.ts.map +0 -1
- package/dist/runtime/threads.d.ts +0 -34
- package/dist/runtime/threads.d.ts.map +0 -1
- package/dist/runtime/utils.d.ts +0 -10
- package/dist/runtime/utils.d.ts.map +0 -1
- package/dist/runtime.d.ts +0 -6
- package/dist/runtime.d.ts.map +0 -1
- package/dist/storage/base.d.ts +0 -9
- package/dist/storage/base.d.ts.map +0 -1
- package/dist/storage/index.d.ts +0 -3
- package/dist/storage/index.d.ts.map +0 -1
- package/dist/storage/persona.d.ts +0 -29
- package/dist/storage/persona.d.ts.map +0 -1
- package/dist/tools.d.ts +0 -72
- package/dist/tools.d.ts.map +0 -1
- package/dist/types.d.ts +0 -237
- package/dist/types.d.ts.map +0 -1
- package/docs/README.md +0 -13
- package/docs/api-reference.md +0 -16
- package/docs/contributing.md +0 -21
- package/docs/customization.md +0 -74
- package/docs/features.md +0 -7
- package/docs/installation.md +0 -9
- package/docs/messages.md +0 -214
- package/docs/protocols.md +0 -39
- package/docs/transactions.md +0 -121
- package/docs/usage.md +0 -40
- package/jsconfig.node.json +0 -10
- package/playground/index.html +0 -14
- package/playground/src/app.tsx +0 -10
- package/playground/src/chat.tsx +0 -117
- package/playground/src/components/assistant-ui/assistant-modal.tsx +0 -57
- package/playground/src/components/assistant-ui/attachment.tsx +0 -197
- package/playground/src/components/assistant-ui/markdown-text.tsx +0 -228
- package/playground/src/components/assistant-ui/thread-list.tsx +0 -91
- package/playground/src/components/assistant-ui/thread.tsx +0 -302
- package/playground/src/components/assistant-ui/threadlist-sidebar.tsx +0 -59
- package/playground/src/components/assistant-ui/tool-fallback.tsx +0 -93
- package/playground/src/components/assistant-ui/tooltip-icon-button.tsx +0 -42
- package/playground/src/components/chat/logging.tsx +0 -53
- package/playground/src/components/ui/avatar.tsx +0 -51
- package/playground/src/components/ui/button.tsx +0 -60
- package/playground/src/components/ui/dialog.tsx +0 -141
- package/playground/src/components/ui/input.tsx +0 -21
- package/playground/src/components/ui/separator.tsx +0 -26
- package/playground/src/components/ui/sheet.tsx +0 -139
- package/playground/src/components/ui/sidebar.tsx +0 -619
- package/playground/src/components/ui/skeleton.tsx +0 -13
- package/playground/src/components/ui/tooltip.tsx +0 -59
- package/playground/src/hooks/theme.ts +0 -70
- package/playground/src/hooks/use-mobile.ts +0 -19
- package/playground/src/lib/utils.ts +0 -6
- package/playground/src/main.tsx +0 -10
- package/playground/src/styles.css +0 -120
- package/playground/src/tools.ts +0 -149
- package/playground/src/vite-env.d.ts +0 -1
- package/preview-build.sh +0 -23
- package/src/logging.ts +0 -34
- package/src/messages.ts +0 -202
- package/src/projects.ts +0 -57
- package/src/protocol/base.ts +0 -73
- package/src/protocol/index.ts +0 -5
- package/src/protocol/rest.ts +0 -107
- package/src/protocol/transaction.ts +0 -182
- package/src/protocol/webrtc.ts +0 -379
- package/src/protocol/websocket.ts +0 -111
- package/src/runtime/context.ts +0 -88
- package/src/runtime/file-attachment-adapter.ts +0 -48
- package/src/runtime/handlers.ts +0 -322
- package/src/runtime/index.ts +0 -6
- package/src/runtime/listeners.ts +0 -79
- package/src/runtime/protocols.ts +0 -169
- package/src/runtime/threads.ts +0 -105
- package/src/runtime/utils.ts +0 -46
- package/src/runtime.tsx +0 -334
- package/src/storage/base.ts +0 -13
- package/src/storage/index.ts +0 -2
- package/src/storage/persona.ts +0 -138
- package/src/tools.ts +0 -211
- package/src/types.ts +0 -284
- package/tsconfig.node.json +0 -15
package/docs/transactions.md
DELETED
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
# Transactions and Tools
|
|
2
|
-
|
|
3
|
-
The Transaction Protocol in the Persona SDK is designed to handle structured interactions between the client and the Persona API. It allows you to define and execute specific operations (tools) in response to function calls.
|
|
4
|
-
|
|
5
|
-
## How It Works
|
|
6
|
-
|
|
7
|
-
1. **Transaction Handling**: The protocol listens for incoming transactions and invokes the appropriate tool based on the function call.
|
|
8
|
-
2. **Session Management**: It shares the same session as other protocols, ensuring consistency.
|
|
9
|
-
3. **Custom Logic**: You can define custom tools to handle specific function calls.
|
|
10
|
-
|
|
11
|
-
## Usage Example
|
|
12
|
-
|
|
13
|
-
To enable the Transaction Protocol, include it in the `protocols` configuration of the `PersonaRuntimeProvider`:
|
|
14
|
-
|
|
15
|
-
```tsx
|
|
16
|
-
<PersonaRuntimeProvider
|
|
17
|
-
dev
|
|
18
|
-
logger={logger}
|
|
19
|
-
protocols={{
|
|
20
|
-
transaction: async (transaction) => {
|
|
21
|
-
await transaction.invoke({
|
|
22
|
-
get_user_agent: () => navigator.userAgent || 'unknown',
|
|
23
|
-
get_client_date: () => ({ date: new Date().toISOString() }),
|
|
24
|
-
});
|
|
25
|
-
},
|
|
26
|
-
}}
|
|
27
|
-
session="your-session-id"
|
|
28
|
-
apiKey="your-api-key"
|
|
29
|
-
agentId="your-agent-id"
|
|
30
|
-
>
|
|
31
|
-
<YourComponent />
|
|
32
|
-
</PersonaRuntimeProvider>
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
---
|
|
36
|
-
|
|
37
|
-
## Managing Tools
|
|
38
|
-
|
|
39
|
-
### Using the `tools` Prop in PersonaRuntimeProvider
|
|
40
|
-
|
|
41
|
-
The `tools` prop allows you to define custom tools that the Transaction Protocol can invoke in response to function calls.
|
|
42
|
-
|
|
43
|
-
#### 1. As an Object (Legacy, Backward Compatible)
|
|
44
|
-
|
|
45
|
-
> **Important:** When using the legacy object format, your agent configuration must also include the tool schema for each tool. If the schema is missing, the configured tools will not work as expected. This is not required when using the array format with `createTool`.
|
|
46
|
-
|
|
47
|
-
```tsx
|
|
48
|
-
<PersonaRuntimeProvider
|
|
49
|
-
tools={{
|
|
50
|
-
get_user_agent: () => navigator.userAgent || 'unknown',
|
|
51
|
-
get_client_date: () => ({ date: new Date().toISOString() }),
|
|
52
|
-
}}
|
|
53
|
-
...otherProps
|
|
54
|
-
/>
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
#### 2. As an Array of Tool Instances (Recommended)
|
|
58
|
-
|
|
59
|
-
For better type safety, schema support, and documentation, you can define tools using the `createTool` utility:
|
|
60
|
-
|
|
61
|
-
```tsx
|
|
62
|
-
import { createTool } from '@applica-software-guru/persona-sdk';
|
|
63
|
-
|
|
64
|
-
const tools = [
|
|
65
|
-
createTool({
|
|
66
|
-
name: 'sum',
|
|
67
|
-
title: 'Sum two numbers',
|
|
68
|
-
description: 'Sums two numbers and returns the result.',
|
|
69
|
-
parameters: {
|
|
70
|
-
a: { type: 'number', description: 'First number to sum', required: true },
|
|
71
|
-
b: { type: 'number', description: 'Second number to sum', required: true },
|
|
72
|
-
},
|
|
73
|
-
output: {
|
|
74
|
-
result: { type: 'number', description: 'Sum of the two numbers' },
|
|
75
|
-
},
|
|
76
|
-
implementation: async (a: number, b: number) => {
|
|
77
|
-
return { result: a + b };
|
|
78
|
-
},
|
|
79
|
-
}),
|
|
80
|
-
];
|
|
81
|
-
|
|
82
|
-
<PersonaRuntimeProvider
|
|
83
|
-
tools={tools}
|
|
84
|
-
...otherProps
|
|
85
|
-
/>
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
---
|
|
89
|
-
|
|
90
|
-
## Advanced Transaction Handling
|
|
91
|
-
|
|
92
|
-
You can manage transactions manually by inspecting the function call and executing the `complete` or `fail` methods.
|
|
93
|
-
|
|
94
|
-
```tsx
|
|
95
|
-
<PersonaRuntimeProvider
|
|
96
|
-
protocols={{
|
|
97
|
-
transaction: async (transaction) => {
|
|
98
|
-
const { functionCall, persistable } = transaction;
|
|
99
|
-
|
|
100
|
-
try {
|
|
101
|
-
if (functionCall.name === 'get_user_agent') {
|
|
102
|
-
const result = navigator.userAgent || 'unknown';
|
|
103
|
-
await persistable.complete(result);
|
|
104
|
-
} else {
|
|
105
|
-
throw new Error(`Unknown function call: ${functionCall.name}`);
|
|
106
|
-
}
|
|
107
|
-
} catch (error) {
|
|
108
|
-
await persistable.fail({ error: error.message });
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
}}
|
|
112
|
-
...
|
|
113
|
-
/>
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
## Best Practices
|
|
117
|
-
|
|
118
|
-
1. **Tool Naming**: Use descriptive names.
|
|
119
|
-
2. **Error Handling**: Handle errors gracefully.
|
|
120
|
-
3. **Testing**: Test tools thoroughly.
|
|
121
|
-
4. **Security**: Avoid exposing sensitive data.
|
package/docs/usage.md
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
# Usage
|
|
2
|
-
|
|
3
|
-
Here’s an example of how to use the Persona SDK in your chat application:
|
|
4
|
-
|
|
5
|
-
```typescript
|
|
6
|
-
import dynamic from 'next/dynamic';
|
|
7
|
-
|
|
8
|
-
const PersonaRuntimeProvider = dynamic(() => import('@applica-software-guru/persona-sdk').then((mod) => mod.PersonaRuntimeProvider), {
|
|
9
|
-
ssr: false,
|
|
10
|
-
});
|
|
11
|
-
|
|
12
|
-
const logger = new PersonaConsoleLogger();
|
|
13
|
-
|
|
14
|
-
function Chat() {
|
|
15
|
-
return (
|
|
16
|
-
<PersonaRuntimeProvider
|
|
17
|
-
dev
|
|
18
|
-
logger={logger}
|
|
19
|
-
protocols={{
|
|
20
|
-
rest: true,
|
|
21
|
-
webrtc: true,
|
|
22
|
-
websocket: true,
|
|
23
|
-
}}
|
|
24
|
-
session={'<session-id>'}
|
|
25
|
-
apiKey="<api-key>"
|
|
26
|
-
agentId={'<agent-name>'}
|
|
27
|
-
>
|
|
28
|
-
<div className="h-dvh w-full">
|
|
29
|
-
<Thread />
|
|
30
|
-
</div>
|
|
31
|
-
</PersonaRuntimeProvider>
|
|
32
|
-
);
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
**Note**: When using WebRTC, it is recommended to import `PersonaRuntimeProvider` dynamically with `ssr: false` (as shown above) to ensure compatibility with server-side rendering frameworks like Next.js.
|
|
37
|
-
|
|
38
|
-
### Development Mode
|
|
39
|
-
|
|
40
|
-
Use the `dev` prop to enable development mode. This redirects all traffic to a local installation of Persona (e.g., `localhost:8000`).
|
package/jsconfig.node.json
DELETED
package/playground/index.html
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/png" href="/favicon.svg" />
|
|
6
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
7
|
-
<link href="/src/styles.css" rel="stylesheet">
|
|
8
|
-
<title>Persona SDK</title>
|
|
9
|
-
</head>
|
|
10
|
-
<body>
|
|
11
|
-
<div id="app"></div>
|
|
12
|
-
<script type="module" src="/src/main.tsx"></script>
|
|
13
|
-
</body>
|
|
14
|
-
</html>
|
package/playground/src/app.tsx
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
function App() {
|
|
2
|
-
return (
|
|
3
|
-
<div className="flex flex-col items-center justify-center min-h-screen bg-gray-100">
|
|
4
|
-
<h1 className="text-4xl font-bold text-gray-800">Hello, world!</h1>
|
|
5
|
-
<p className="mt-4 text-lg text-gray-600">This is a simple React app.</p>
|
|
6
|
-
</div>
|
|
7
|
-
);
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default App;
|
package/playground/src/chat.tsx
DELETED
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import { Thread } from '@/components/assistant-ui/thread';
|
|
2
|
-
import { PersonaRuntimeProvider, PersonaConsoleLogger, Session } from '@applica-software-guru/persona-sdk';
|
|
3
|
-
import { useMemo } from 'react';
|
|
4
|
-
import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar';
|
|
5
|
-
import { ThreadListSidebar } from '@/components/assistant-ui/threadlist-sidebar';
|
|
6
|
-
import { SunIcon, MoonIcon, RefreshCcwDot } from 'lucide-react';
|
|
7
|
-
import { useColorScheme } from './hooks/theme';
|
|
8
|
-
|
|
9
|
-
const logger = new PersonaConsoleLogger();
|
|
10
|
-
|
|
11
|
-
function generateSID() {
|
|
12
|
-
const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
|
13
|
-
let sid = '';
|
|
14
|
-
for (let i = 0; i < 16; i++) {
|
|
15
|
-
sid += chars.charAt(Math.floor(Math.random() * chars.length));
|
|
16
|
-
}
|
|
17
|
-
return sid;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function getQueryParam(param: string): string | null {
|
|
21
|
-
const urlParams = new URLSearchParams(window.location.search);
|
|
22
|
-
return urlParams.get(param);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function Chat() {
|
|
26
|
-
const sidebar = getQueryParam('sidebar') === 'true';
|
|
27
|
-
const enableAttachments = getQueryParam('enableAttachments') !== 'false';
|
|
28
|
-
const agentId = getQueryParam('agentId');
|
|
29
|
-
const userId = getQueryParam('userId') || 'anonymous';
|
|
30
|
-
const apiKey = getQueryParam('apiKey');
|
|
31
|
-
const sid = getQueryParam('sid');
|
|
32
|
-
|
|
33
|
-
const session = useMemo((): Session => {
|
|
34
|
-
if (sid) {
|
|
35
|
-
return sid;
|
|
36
|
-
}
|
|
37
|
-
return generateSID();
|
|
38
|
-
}, [sid]);
|
|
39
|
-
|
|
40
|
-
return (
|
|
41
|
-
<PersonaRuntimeProvider
|
|
42
|
-
// dev
|
|
43
|
-
// baseUrl="http://localhost:8000"
|
|
44
|
-
logger={logger}
|
|
45
|
-
context={{
|
|
46
|
-
data: {
|
|
47
|
-
username: 'Roberto',
|
|
48
|
-
userAgent: 'Playground Client v1.0',
|
|
49
|
-
},
|
|
50
|
-
}}
|
|
51
|
-
tools={[]}
|
|
52
|
-
protocols={{
|
|
53
|
-
rest: true,
|
|
54
|
-
webrtc: false,
|
|
55
|
-
websocket: true,
|
|
56
|
-
}}
|
|
57
|
-
session={session}
|
|
58
|
-
apiKey={apiKey!}
|
|
59
|
-
userId={userId}
|
|
60
|
-
agentId={agentId!}
|
|
61
|
-
enableAttachments={enableAttachments}
|
|
62
|
-
threads={sidebar}
|
|
63
|
-
onThreadCreate={(threadId) => {
|
|
64
|
-
logger.info('Thread created:', threadId);
|
|
65
|
-
}}
|
|
66
|
-
onThreadSwitch={(threadId) => {
|
|
67
|
-
logger.info('Switched to thread:', threadId);
|
|
68
|
-
}}
|
|
69
|
-
onThreadRename={(threadId, newTitle) => {
|
|
70
|
-
logger.info('Thread renamed:', threadId, newTitle);
|
|
71
|
-
}}
|
|
72
|
-
onThreadArchive={(threadId) => {
|
|
73
|
-
logger.info('Thread archived:', threadId);
|
|
74
|
-
}}
|
|
75
|
-
onThreadDelete={(threadId) => {
|
|
76
|
-
logger.info('Thread deleted:', threadId);
|
|
77
|
-
}}
|
|
78
|
-
>
|
|
79
|
-
{sidebar ? (
|
|
80
|
-
<SidebarProvider>
|
|
81
|
-
<div className="flex h-dvh w-full">
|
|
82
|
-
<ThreadListSidebar />
|
|
83
|
-
<SidebarInset>
|
|
84
|
-
<SidebarTrigger className="absolute top-4 left-4" />
|
|
85
|
-
<ThemeToggle />
|
|
86
|
-
<Thread />
|
|
87
|
-
</SidebarInset>
|
|
88
|
-
</div>
|
|
89
|
-
</SidebarProvider>
|
|
90
|
-
) : (
|
|
91
|
-
<div className="relative h-dvh w-full">
|
|
92
|
-
<ThemeToggle />
|
|
93
|
-
<Thread />
|
|
94
|
-
</div>
|
|
95
|
-
)}
|
|
96
|
-
</PersonaRuntimeProvider>
|
|
97
|
-
);
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
function ThemeToggle() {
|
|
101
|
-
const { theme, toggle } = useColorScheme();
|
|
102
|
-
const title = theme === 'auto' ? 'System theme (auto)' : theme === 'dark' ? 'Dark mode' : 'Light mode';
|
|
103
|
-
|
|
104
|
-
return (
|
|
105
|
-
<button
|
|
106
|
-
onClick={toggle}
|
|
107
|
-
aria-label={`Toggle theme, current: ${title}`}
|
|
108
|
-
title={`Toggle theme, current: ${title}`}
|
|
109
|
-
type="button"
|
|
110
|
-
className="absolute top-4 right-4 z-50 pointer-events-auto inline-flex h-10 w-10 items-center justify-center rounded-full border border-border bg-card p-2 text-foreground shadow-sm hover:cursor-pointer"
|
|
111
|
-
>
|
|
112
|
-
{theme === 'dark' ? <MoonIcon /> : theme === 'light' ? <SunIcon /> : <RefreshCcwDot />}
|
|
113
|
-
</button>
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
export { Chat };
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { BotIcon, ChevronDownIcon } from 'lucide-react';
|
|
4
|
-
|
|
5
|
-
import { type FC, forwardRef } from 'react';
|
|
6
|
-
import { AssistantModalPrimitive } from '@assistant-ui/react';
|
|
7
|
-
|
|
8
|
-
import { Thread } from '@/components/assistant-ui/thread';
|
|
9
|
-
import { TooltipIconButton } from '@/components/assistant-ui/tooltip-icon-button';
|
|
10
|
-
|
|
11
|
-
export const AssistantModal: FC = () => {
|
|
12
|
-
return (
|
|
13
|
-
<AssistantModalPrimitive.Root>
|
|
14
|
-
<AssistantModalPrimitive.Anchor className="fixed bottom-4 right-4 size-11">
|
|
15
|
-
<AssistantModalPrimitive.Trigger asChild>
|
|
16
|
-
<AssistantModalButton />
|
|
17
|
-
</AssistantModalPrimitive.Trigger>
|
|
18
|
-
</AssistantModalPrimitive.Anchor>
|
|
19
|
-
<AssistantModalPrimitive.Content
|
|
20
|
-
sideOffset={16}
|
|
21
|
-
className="bg-popover text-popover-foreground z-50 h-[500px] w-[400px] overflow-clip rounded-xl border p-0 shadow-md outline-none [&>.aui-thread-root]:bg-inherit data-[state=closed]:animate-out data-[state=open]:animate-in data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out data-[state=open]:zoom-in data-[state=open]:slide-in-from-bottom-1/2 data-[state=open]:slide-in-from-right-1/2 data-[state=closed]:slide-out-to-bottom-1/2 data-[state=closed]:slide-out-to-right-1/2"
|
|
22
|
-
>
|
|
23
|
-
<Thread />
|
|
24
|
-
</AssistantModalPrimitive.Content>
|
|
25
|
-
</AssistantModalPrimitive.Root>
|
|
26
|
-
);
|
|
27
|
-
};
|
|
28
|
-
|
|
29
|
-
type AssistantModalButtonProps = { 'data-state'?: 'open' | 'closed' };
|
|
30
|
-
|
|
31
|
-
const AssistantModalButton = forwardRef<HTMLButtonElement, AssistantModalButtonProps>(({ 'data-state': state, ...rest }, ref) => {
|
|
32
|
-
const tooltip = state === 'open' ? 'Close Assistant' : 'Open Assistant';
|
|
33
|
-
|
|
34
|
-
return (
|
|
35
|
-
<TooltipIconButton
|
|
36
|
-
variant="default"
|
|
37
|
-
tooltip={tooltip}
|
|
38
|
-
side="left"
|
|
39
|
-
{...rest}
|
|
40
|
-
className="size-full rounded-full shadow transition-transform hover:scale-110 active:scale-90"
|
|
41
|
-
ref={ref}
|
|
42
|
-
>
|
|
43
|
-
<BotIcon
|
|
44
|
-
data-state={state}
|
|
45
|
-
className="absolute size-6 transition-all data-[state=closed]:rotate-0 data-[state=open]:rotate-90 data-[state=closed]:scale-100 data-[state=open]:scale-0"
|
|
46
|
-
/>
|
|
47
|
-
|
|
48
|
-
<ChevronDownIcon
|
|
49
|
-
data-state={state}
|
|
50
|
-
className="absolute size-6 transition-all data-[state=closed]:-rotate-90 data-[state=open]:rotate-0 data-[state=closed]:scale-0 data-[state=open]:scale-100"
|
|
51
|
-
/>
|
|
52
|
-
<span className="sr-only">{tooltip}</span>
|
|
53
|
-
</TooltipIconButton>
|
|
54
|
-
);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
AssistantModalButton.displayName = 'AssistantModalButton';
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { PropsWithChildren, useEffect, useState, type FC } from 'react';
|
|
4
|
-
import { XIcon, PlusIcon, FileText } from 'lucide-react';
|
|
5
|
-
import { AttachmentPrimitive, ComposerPrimitive, MessagePrimitive, useAssistantState, useAssistantApi } from '@assistant-ui/react';
|
|
6
|
-
import { useShallow } from 'zustand/shallow';
|
|
7
|
-
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
|
|
8
|
-
import { Dialog, DialogTitle, DialogContent, DialogTrigger } from '@/components/ui/dialog';
|
|
9
|
-
import { Avatar, AvatarImage, AvatarFallback } from '@/components/ui/avatar';
|
|
10
|
-
import { TooltipIconButton } from '@/components/assistant-ui/tooltip-icon-button';
|
|
11
|
-
import { cn } from '@/lib/utils';
|
|
12
|
-
|
|
13
|
-
const useFileSrc = (file: File | undefined) => {
|
|
14
|
-
const [src, setSrc] = useState<string | undefined>(undefined);
|
|
15
|
-
|
|
16
|
-
useEffect(() => {
|
|
17
|
-
if (!file) {
|
|
18
|
-
setSrc(undefined);
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const objectUrl = URL.createObjectURL(file);
|
|
23
|
-
setSrc(objectUrl);
|
|
24
|
-
|
|
25
|
-
return () => {
|
|
26
|
-
URL.revokeObjectURL(objectUrl);
|
|
27
|
-
};
|
|
28
|
-
}, [file]);
|
|
29
|
-
|
|
30
|
-
return src;
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const useAttachmentSrc = () => {
|
|
34
|
-
const { file, src } = useAssistantState(
|
|
35
|
-
useShallow(({ attachment }): { file?: File; src?: string } => {
|
|
36
|
-
if (attachment.type !== 'image') return {};
|
|
37
|
-
if (attachment.file) return { file: attachment.file };
|
|
38
|
-
const src = attachment.content?.filter((c) => c.type === 'image')[0]?.image;
|
|
39
|
-
if (!src) return {};
|
|
40
|
-
return { src };
|
|
41
|
-
}),
|
|
42
|
-
);
|
|
43
|
-
|
|
44
|
-
return useFileSrc(file) ?? src;
|
|
45
|
-
};
|
|
46
|
-
|
|
47
|
-
type AttachmentPreviewProps = {
|
|
48
|
-
src: string;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const AttachmentPreview: FC<AttachmentPreviewProps> = ({ src }) => {
|
|
52
|
-
const [isLoaded, setIsLoaded] = useState(false);
|
|
53
|
-
return (
|
|
54
|
-
<img
|
|
55
|
-
src={src}
|
|
56
|
-
alt="Image Preview"
|
|
57
|
-
width={1}
|
|
58
|
-
height={1}
|
|
59
|
-
className={
|
|
60
|
-
isLoaded
|
|
61
|
-
? 'aui-attachment-preview-image-loaded block h-auto max-h-[80vh] w-auto max-w-full object-contain'
|
|
62
|
-
: 'aui-attachment-preview-image-loading hidden'
|
|
63
|
-
}
|
|
64
|
-
onLoad={() => setIsLoaded(true)}
|
|
65
|
-
/>
|
|
66
|
-
);
|
|
67
|
-
};
|
|
68
|
-
|
|
69
|
-
const AttachmentPreviewDialog: FC<PropsWithChildren> = ({ children }) => {
|
|
70
|
-
const src = useAttachmentSrc();
|
|
71
|
-
|
|
72
|
-
if (!src) return children;
|
|
73
|
-
|
|
74
|
-
return (
|
|
75
|
-
<Dialog>
|
|
76
|
-
<DialogTrigger className="aui-attachment-preview-trigger cursor-pointer transition-colors hover:bg-accent/50" asChild>
|
|
77
|
-
{children}
|
|
78
|
-
</DialogTrigger>
|
|
79
|
-
<DialogContent className="aui-attachment-preview-dialog-content p-2 sm:max-w-3xl [&>button]:rounded-full [&>button]:bg-foreground/60 [&>button]:p-1 [&>button]:opacity-100 [&>button]:ring-0! [&_svg]:text-background [&>button]:hover:[&_svg]:text-destructive">
|
|
80
|
-
<DialogTitle className="aui-sr-only sr-only">Image Attachment Preview</DialogTitle>
|
|
81
|
-
<div className="aui-attachment-preview relative mx-auto flex max-h-[80dvh] w-full items-center justify-center overflow-hidden bg-background">
|
|
82
|
-
<AttachmentPreview src={src} />
|
|
83
|
-
</div>
|
|
84
|
-
</DialogContent>
|
|
85
|
-
</Dialog>
|
|
86
|
-
);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const AttachmentThumb: FC = () => {
|
|
90
|
-
const isImage = useAssistantState(({ attachment }) => attachment.type === 'image');
|
|
91
|
-
const src = useAttachmentSrc();
|
|
92
|
-
|
|
93
|
-
return (
|
|
94
|
-
<Avatar className="aui-attachment-tile-avatar h-full w-full rounded-none">
|
|
95
|
-
<AvatarImage src={src} alt="Attachment preview" className="aui-attachment-tile-image object-cover" />
|
|
96
|
-
<AvatarFallback delayMs={isImage ? 200 : 0}>
|
|
97
|
-
<FileText className="aui-attachment-tile-fallback-icon size-8 text-muted-foreground" />
|
|
98
|
-
</AvatarFallback>
|
|
99
|
-
</Avatar>
|
|
100
|
-
);
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
const AttachmentUI: FC = () => {
|
|
104
|
-
const api = useAssistantApi();
|
|
105
|
-
const isComposer = api.attachment.source === 'composer';
|
|
106
|
-
|
|
107
|
-
const isImage = useAssistantState(({ attachment }) => attachment.type === 'image');
|
|
108
|
-
const typeLabel = useAssistantState(({ attachment }) => {
|
|
109
|
-
const type = attachment.type;
|
|
110
|
-
switch (type) {
|
|
111
|
-
case 'image':
|
|
112
|
-
return 'Image';
|
|
113
|
-
case 'document':
|
|
114
|
-
return 'Document';
|
|
115
|
-
case 'file':
|
|
116
|
-
return 'File';
|
|
117
|
-
default:
|
|
118
|
-
const _exhaustiveCheck: never = type;
|
|
119
|
-
throw new Error(`Unknown attachment type: ${_exhaustiveCheck}`);
|
|
120
|
-
}
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
return (
|
|
124
|
-
<Tooltip>
|
|
125
|
-
<AttachmentPrimitive.Root
|
|
126
|
-
className={cn('aui-attachment-root relative', isImage && 'aui-attachment-root-composer only:[&>#attachment-tile]:size-24')}
|
|
127
|
-
>
|
|
128
|
-
<AttachmentPreviewDialog>
|
|
129
|
-
<TooltipTrigger asChild>
|
|
130
|
-
<div
|
|
131
|
-
className={cn(
|
|
132
|
-
'aui-attachment-tile size-14 cursor-pointer overflow-hidden rounded-[14px] border bg-muted transition-opacity hover:opacity-75',
|
|
133
|
-
isComposer && 'aui-attachment-tile-composer border-foreground/20',
|
|
134
|
-
)}
|
|
135
|
-
role="button"
|
|
136
|
-
id="attachment-tile"
|
|
137
|
-
aria-label={`${typeLabel} attachment`}
|
|
138
|
-
>
|
|
139
|
-
<AttachmentThumb />
|
|
140
|
-
</div>
|
|
141
|
-
</TooltipTrigger>
|
|
142
|
-
</AttachmentPreviewDialog>
|
|
143
|
-
{isComposer && <AttachmentRemove />}
|
|
144
|
-
</AttachmentPrimitive.Root>
|
|
145
|
-
<TooltipContent side="top">
|
|
146
|
-
<AttachmentPrimitive.Name />
|
|
147
|
-
</TooltipContent>
|
|
148
|
-
</Tooltip>
|
|
149
|
-
);
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
const AttachmentRemove: FC = () => {
|
|
153
|
-
return (
|
|
154
|
-
<AttachmentPrimitive.Remove asChild>
|
|
155
|
-
<TooltipIconButton
|
|
156
|
-
tooltip="Remove file"
|
|
157
|
-
className="aui-attachment-tile-remove absolute top-1.5 right-1.5 size-3.5 rounded-full bg-white text-muted-foreground opacity-100 shadow-sm hover:bg-white! [&_svg]:text-black hover:[&_svg]:text-destructive"
|
|
158
|
-
side="top"
|
|
159
|
-
>
|
|
160
|
-
<XIcon className="aui-attachment-remove-icon size-3 dark:stroke-[2.5px]" />
|
|
161
|
-
</TooltipIconButton>
|
|
162
|
-
</AttachmentPrimitive.Remove>
|
|
163
|
-
);
|
|
164
|
-
};
|
|
165
|
-
|
|
166
|
-
export const UserMessageAttachments: FC = () => {
|
|
167
|
-
return (
|
|
168
|
-
<div className="aui-user-message-attachments-end col-span-full col-start-1 row-start-1 flex w-full flex-row justify-end gap-2">
|
|
169
|
-
<MessagePrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
170
|
-
</div>
|
|
171
|
-
);
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
export const ComposerAttachments: FC = () => {
|
|
175
|
-
return (
|
|
176
|
-
<div className="aui-composer-attachments mb-2 flex w-full flex-row items-center gap-2 overflow-x-auto px-1.5 pt-0.5 pb-1 empty:hidden">
|
|
177
|
-
<ComposerPrimitive.Attachments components={{ Attachment: AttachmentUI }} />
|
|
178
|
-
</div>
|
|
179
|
-
);
|
|
180
|
-
};
|
|
181
|
-
|
|
182
|
-
export const ComposerAddAttachment: FC = () => {
|
|
183
|
-
return (
|
|
184
|
-
<ComposerPrimitive.AddAttachment asChild>
|
|
185
|
-
<TooltipIconButton
|
|
186
|
-
tooltip="Add Attachment"
|
|
187
|
-
side="bottom"
|
|
188
|
-
variant="ghost"
|
|
189
|
-
size="icon"
|
|
190
|
-
className="aui-composer-add-attachment size-[34px] rounded-full p-1 font-semibold text-xs hover:bg-muted-foreground/15 dark:border-muted-foreground/15 dark:hover:bg-muted-foreground/30"
|
|
191
|
-
aria-label="Add Attachment"
|
|
192
|
-
>
|
|
193
|
-
<PlusIcon className="aui-attachment-add-icon size-5 stroke-[1.5px]" />
|
|
194
|
-
</TooltipIconButton>
|
|
195
|
-
</ComposerPrimitive.AddAttachment>
|
|
196
|
-
);
|
|
197
|
-
};
|