@promptbook/cli 0.103.0-52 → 0.103.0-53
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/apps/agents-server/README.md +1 -1
- package/apps/agents-server/config.ts +3 -3
- package/apps/agents-server/next.config.ts +1 -1
- package/apps/agents-server/public/sw.js +16 -0
- package/apps/agents-server/src/app/AddAgentButton.tsx +24 -4
- package/apps/agents-server/src/app/actions.ts +15 -13
- package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackClient.tsx +541 -0
- package/apps/agents-server/src/app/admin/chat-feedback/page.tsx +22 -0
- package/apps/agents-server/src/app/admin/chat-history/ChatHistoryClient.tsx +532 -0
- package/apps/agents-server/src/app/admin/chat-history/page.tsx +21 -0
- package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +241 -27
- package/apps/agents-server/src/app/admin/models/page.tsx +22 -0
- package/apps/agents-server/src/app/admin/users/[userId]/UserDetailClient.tsx +131 -0
- package/apps/agents-server/src/app/admin/users/[userId]/page.tsx +21 -0
- package/apps/agents-server/src/app/admin/users/page.tsx +18 -0
- package/apps/agents-server/src/app/agents/[agentName]/ClearAgentChatFeedbackButton.tsx +63 -0
- package/apps/agents-server/src/app/agents/[agentName]/ClearAgentChatHistoryButton.tsx +63 -0
- package/apps/agents-server/src/app/agents/[agentName]/CloneAgentButton.tsx +41 -0
- package/apps/agents-server/src/app/agents/[agentName]/InstallPwaButton.tsx +74 -0
- package/apps/agents-server/src/app/agents/[agentName]/ServiceWorkerRegister.tsx +24 -0
- package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +19 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/agents/route.ts +67 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +3 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/voice/route.ts +177 -0
- package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +3 -0
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/AgentBookAndChat.tsx +53 -1
- package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +11 -11
- package/apps/agents-server/src/app/agents/[agentName]/history/RestoreVersionButton.tsx +46 -0
- package/apps/agents-server/src/app/agents/[agentName]/history/actions.ts +12 -0
- package/apps/agents-server/src/app/agents/[agentName]/history/page.tsx +62 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +80 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +92 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +92 -0
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +61 -0
- package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +102 -0
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +41 -22
- package/apps/agents-server/src/app/api/agents/[agentName]/clone/route.ts +47 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +19 -0
- package/apps/agents-server/src/app/api/agents/route.ts +22 -13
- package/apps/agents-server/src/app/api/auth/login/route.ts +6 -44
- package/apps/agents-server/src/app/api/chat-feedback/[id]/route.ts +38 -0
- package/apps/agents-server/src/app/api/chat-feedback/route.ts +157 -0
- package/apps/agents-server/src/app/api/chat-history/[id]/route.ts +37 -0
- package/apps/agents-server/src/app/api/chat-history/route.ts +147 -0
- package/apps/agents-server/src/app/api/federated-agents/route.ts +17 -0
- package/apps/agents-server/src/app/api/upload/route.ts +9 -1
- package/apps/agents-server/src/app/docs/[docId]/page.tsx +62 -0
- package/apps/agents-server/src/app/docs/page.tsx +33 -0
- package/apps/agents-server/src/app/layout.tsx +29 -3
- package/apps/agents-server/src/app/manifest.ts +109 -0
- package/apps/agents-server/src/app/page.tsx +8 -45
- package/apps/agents-server/src/app/recycle-bin/RestoreAgentButton.tsx +40 -0
- package/apps/agents-server/src/app/recycle-bin/actions.ts +27 -0
- package/apps/agents-server/src/app/recycle-bin/page.tsx +58 -0
- package/apps/agents-server/src/app/restricted/page.tsx +33 -0
- package/apps/agents-server/src/app/test/og-image/README.md +1 -0
- package/apps/agents-server/src/app/test/og-image/opengraph-image.tsx +37 -0
- package/apps/agents-server/src/app/test/og-image/page.tsx +22 -0
- package/apps/agents-server/src/components/Footer/Footer.tsx +175 -0
- package/apps/agents-server/src/components/Header/Header.tsx +445 -79
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +46 -14
- package/apps/agents-server/src/components/Homepage/AgentsList.tsx +58 -0
- package/apps/agents-server/src/components/Homepage/Card.tsx +1 -1
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSection.tsx +21 -0
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSectionClient.tsx +183 -0
- package/apps/agents-server/src/components/Homepage/ModelsSection.tsx +75 -0
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +28 -3
- package/apps/agents-server/src/components/LoginDialog/LoginDialog.tsx +18 -17
- package/apps/agents-server/src/components/Portal/Portal.tsx +38 -0
- package/apps/agents-server/src/components/UsersList/UsersList.tsx +82 -131
- package/apps/agents-server/src/components/UsersList/useUsersAdmin.ts +139 -0
- package/apps/agents-server/src/database/metadataDefaults.ts +38 -6
- package/apps/agents-server/src/middleware.ts +146 -93
- package/apps/agents-server/src/tools/$provideServer.ts +2 -2
- package/apps/agents-server/src/utils/authenticateUser.ts +42 -0
- package/apps/agents-server/src/utils/chatFeedbackAdmin.ts +96 -0
- package/apps/agents-server/src/utils/chatHistoryAdmin.ts +96 -0
- package/apps/agents-server/src/utils/getEffectiveFederatedServers.ts +22 -0
- package/apps/agents-server/src/utils/getFederatedAgents.ts +31 -8
- package/apps/agents-server/src/utils/getFederatedServersFromMetadata.ts +10 -0
- package/apps/agents-server/src/utils/getVisibleCommitmentDefinitions.ts +12 -0
- package/apps/agents-server/src/utils/isUserAdmin.ts +2 -2
- package/apps/agents-server/vercel.json +7 -0
- package/esm/index.es.js +153 -2
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +8 -1
- package/esm/typings/src/_packages/components.index.d.ts +2 -0
- package/esm/typings/src/_packages/core.index.d.ts +6 -0
- package/esm/typings/src/_packages/types.index.d.ts +2 -0
- package/esm/typings/src/_packages/utils.index.d.ts +2 -0
- package/esm/typings/src/book-2.0/agent-source/AgentModelRequirements.d.ts +7 -0
- package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +4 -0
- package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +12 -0
- package/esm/typings/src/book-components/icons/MicIcon.d.ts +8 -0
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +17 -0
- package/esm/typings/src/commitments/MESSAGE/AgentMessageCommitmentDefinition.d.ts +28 -0
- package/esm/typings/src/commitments/MESSAGE/UserMessageCommitmentDefinition.d.ts +28 -0
- package/esm/typings/src/commitments/index.d.ts +20 -1
- package/esm/typings/src/execution/LlmExecutionTools.d.ts +9 -0
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +2 -1
- package/esm/typings/src/llm-providers/agent/RemoteAgent.d.ts +10 -1
- package/esm/typings/src/utils/normalization/normalizeMessageText.d.ts +9 -0
- package/esm/typings/src/utils/normalization/normalizeMessageText.test.d.ts +1 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +153 -2
- package/umd/index.umd.js.map +1 -1
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
2
|
+
import { HistoryIcon } from 'lucide-react';
|
|
3
|
+
import Link from 'next/link';
|
|
4
|
+
import { RestoreVersionButton } from './RestoreVersionButton';
|
|
5
|
+
|
|
6
|
+
export const metadata = {
|
|
7
|
+
title: 'Agent History',
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export default async function AgentHistoryPage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
11
|
+
const { agentName } = await params;
|
|
12
|
+
const collection = await $provideAgentCollectionForServer();
|
|
13
|
+
const history = await collection.listAgentHistory(agentName);
|
|
14
|
+
|
|
15
|
+
return (
|
|
16
|
+
<div className="container mx-auto p-6 max-w-4xl">
|
|
17
|
+
<header className="flex items-center gap-4 mb-8">
|
|
18
|
+
<div className="bg-blue-100 p-3 rounded-full">
|
|
19
|
+
<HistoryIcon className="w-8 h-8 text-blue-600" />
|
|
20
|
+
</div>
|
|
21
|
+
<div>
|
|
22
|
+
<h1 className="text-3xl font-bold text-gray-900">History: {agentName}</h1>
|
|
23
|
+
<p className="text-gray-600">
|
|
24
|
+
Previous versions of this agent. <Link href={`/agents/${agentName}`} className="text-blue-600 hover:underline">Back to agent</Link>
|
|
25
|
+
</p>
|
|
26
|
+
</div>
|
|
27
|
+
</header>
|
|
28
|
+
|
|
29
|
+
{history.length === 0 ? (
|
|
30
|
+
<div className="text-center py-12 bg-gray-50 rounded-lg border border-dashed border-gray-300">
|
|
31
|
+
<p className="text-gray-500 text-lg">No history found</p>
|
|
32
|
+
</div>
|
|
33
|
+
) : (
|
|
34
|
+
<div className="relative border-l border-gray-200 ml-4">
|
|
35
|
+
{history.map((item, index) => (
|
|
36
|
+
<div key={item.id} className="mb-8 ml-6">
|
|
37
|
+
<span className="absolute flex items-center justify-center w-6 h-6 bg-blue-100 rounded-full -left-3 ring-8 ring-white">
|
|
38
|
+
<span className="w-3 h-3 bg-blue-600 rounded-full"></span>
|
|
39
|
+
</span>
|
|
40
|
+
<div className="p-4 bg-white border border-gray-200 rounded-lg shadow-sm">
|
|
41
|
+
<div className="flex justify-between items-start mb-2">
|
|
42
|
+
<div>
|
|
43
|
+
<time className="block mb-1 text-sm font-normal leading-none text-gray-400">
|
|
44
|
+
{new Date(item.createdAt).toLocaleString()}
|
|
45
|
+
</time>
|
|
46
|
+
<h3 className="text-lg font-semibold text-gray-900">
|
|
47
|
+
Version {history.length - index}
|
|
48
|
+
</h3>
|
|
49
|
+
<p className="text-sm text-gray-500">
|
|
50
|
+
Hash: <code className="bg-gray-100 px-1 rounded">{item.agentHash.substring(0, 8)}</code>
|
|
51
|
+
</p>
|
|
52
|
+
</div>
|
|
53
|
+
<RestoreVersionButton agentName={agentName} historyId={item.id} />
|
|
54
|
+
</div>
|
|
55
|
+
</div>
|
|
56
|
+
</div>
|
|
57
|
+
))}
|
|
58
|
+
</div>
|
|
59
|
+
)}
|
|
60
|
+
</div>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
|
+
import { serializeError } from '@promptbook-local/utils';
|
|
3
|
+
import { ImageResponse } from 'next/og';
|
|
4
|
+
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
5
|
+
import { Color } from '../../../../../../../../src/utils/color/Color';
|
|
6
|
+
import { keepUnused } from '../../../../../../../../src/utils/organization/keepUnused';
|
|
7
|
+
import { getAgentName, getAgentProfile } from '../../_utils';
|
|
8
|
+
|
|
9
|
+
const size = {
|
|
10
|
+
width: 256,
|
|
11
|
+
height: 256,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export async function GET(request: Request, { params }: { params: Promise<{ agentName: string }> }) {
|
|
15
|
+
keepUnused(request /* <- Note: We dont need `request` parameter */);
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const agentName = await getAgentName(params);
|
|
19
|
+
const agentProfile = await getAgentProfile(agentName);
|
|
20
|
+
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
21
|
+
|
|
22
|
+
return new ImageResponse(
|
|
23
|
+
(
|
|
24
|
+
<div
|
|
25
|
+
style={{
|
|
26
|
+
width: '100%',
|
|
27
|
+
height: '100%',
|
|
28
|
+
backgroundColor: 'transparent',
|
|
29
|
+
display: 'flex',
|
|
30
|
+
alignItems: 'center',
|
|
31
|
+
justifyContent: 'center',
|
|
32
|
+
borderRadius: '50%',
|
|
33
|
+
overflow: 'hidden',
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
<div
|
|
37
|
+
style={{
|
|
38
|
+
width: '100%',
|
|
39
|
+
height: '100%',
|
|
40
|
+
backgroundColor: agentColor.toHex(),
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
47
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
48
|
+
<img src={agentProfile.meta.image!} alt="Agent Icon" />
|
|
49
|
+
</div>
|
|
50
|
+
</div>
|
|
51
|
+
),
|
|
52
|
+
{
|
|
53
|
+
...size,
|
|
54
|
+
emoji: 'openmoji',
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
} catch (error) {
|
|
58
|
+
assertsError(error);
|
|
59
|
+
|
|
60
|
+
console.error(error);
|
|
61
|
+
|
|
62
|
+
return new Response(
|
|
63
|
+
JSON.stringify(
|
|
64
|
+
serializeError(error),
|
|
65
|
+
// <- TODO: [🐱🚀] Rename `serializeError` to `errorToJson`
|
|
66
|
+
null,
|
|
67
|
+
4,
|
|
68
|
+
// <- TODO: [🐱🚀] Allow to configure pretty print for agent server
|
|
69
|
+
),
|
|
70
|
+
{
|
|
71
|
+
status: 400, // <- TODO: [🐱🚀] Make `errorToHttpStatusCode`
|
|
72
|
+
headers: { 'Content-Type': 'application/json' },
|
|
73
|
+
},
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* TODO: [🦚] DRY
|
|
80
|
+
*/
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
|
+
import { serializeError } from '@promptbook-local/utils';
|
|
3
|
+
import { ImageResponse } from 'next/og';
|
|
4
|
+
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
5
|
+
import { Color } from '../../../../../../../../src/utils/color/Color';
|
|
6
|
+
import { textColor } from '../../../../../../../../src/utils/color/operators/furthest';
|
|
7
|
+
import { grayscale } from '../../../../../../../../src/utils/color/operators/grayscale';
|
|
8
|
+
import { keepUnused } from '../../../../../../../../src/utils/organization/keepUnused';
|
|
9
|
+
import { getAgentName, getAgentProfile } from '../../_utils';
|
|
10
|
+
|
|
11
|
+
const size = {
|
|
12
|
+
width: 1920,
|
|
13
|
+
height: 1080,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export async function GET(request: Request, { params }: { params: Promise<{ agentName: string }> }) {
|
|
17
|
+
keepUnused(request /* <- Note: We dont need `request` parameter */);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const agentName = await getAgentName(params);
|
|
21
|
+
const agentProfile = await getAgentProfile(agentName);
|
|
22
|
+
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
23
|
+
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
24
|
+
|
|
25
|
+
return new ImageResponse(
|
|
26
|
+
(
|
|
27
|
+
<div
|
|
28
|
+
style={{
|
|
29
|
+
width: '100%',
|
|
30
|
+
height: '100%',
|
|
31
|
+
backgroundColor: backgroundColor.toHex(),
|
|
32
|
+
color: agentColor.then(textColor).toHex(),
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
style={{
|
|
40
|
+
width: '40%',
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
47
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
48
|
+
<img
|
|
49
|
+
style={{
|
|
50
|
+
width: '80%',
|
|
51
|
+
backgroundColor: agentColor.toHex(),
|
|
52
|
+
borderRadius: '50%',
|
|
53
|
+
}}
|
|
54
|
+
src={agentProfile.meta.image!}
|
|
55
|
+
alt="Agent Icon"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
<div style={{ width: '60%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
59
|
+
<h1 style={{ fontSize: '110px' }}>{agentProfile.meta.fullname || agentName}</h1>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
),
|
|
63
|
+
{
|
|
64
|
+
...size,
|
|
65
|
+
emoji: 'openmoji',
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
assertsError(error);
|
|
70
|
+
|
|
71
|
+
console.error(error);
|
|
72
|
+
|
|
73
|
+
return new Response(
|
|
74
|
+
JSON.stringify(
|
|
75
|
+
serializeError(error),
|
|
76
|
+
// <- TODO: [🐱🚀] Rename `serializeError` to `errorToJson`
|
|
77
|
+
null,
|
|
78
|
+
4,
|
|
79
|
+
// <- TODO: [🐱🚀] Allow to configure pretty print for agent server
|
|
80
|
+
),
|
|
81
|
+
{
|
|
82
|
+
status: 400, // <- TODO: [🐱🚀] Make `errorToHttpStatusCode`
|
|
83
|
+
headers: { 'Content-Type': 'application/json' },
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* TODO: [🦚] DRY
|
|
91
|
+
* TODO: [🦚] This should be the true screenshot NOT just image + Agent name
|
|
92
|
+
*/
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
|
+
import { serializeError } from '@promptbook-local/utils';
|
|
3
|
+
import { ImageResponse } from 'next/og';
|
|
4
|
+
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
5
|
+
import { Color } from '../../../../../../../../src/utils/color/Color';
|
|
6
|
+
import { textColor } from '../../../../../../../../src/utils/color/operators/furthest';
|
|
7
|
+
import { grayscale } from '../../../../../../../../src/utils/color/operators/grayscale';
|
|
8
|
+
import { keepUnused } from '../../../../../../../../src/utils/organization/keepUnused';
|
|
9
|
+
import { getAgentName, getAgentProfile } from '../../_utils';
|
|
10
|
+
|
|
11
|
+
const size = {
|
|
12
|
+
width: 1080,
|
|
13
|
+
height: 1920,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export async function GET(request: Request, { params }: { params: Promise<{ agentName: string }> }) {
|
|
17
|
+
keepUnused(request /* <- Note: We dont need `request` parameter */);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
const agentName = await getAgentName(params);
|
|
21
|
+
const agentProfile = await getAgentProfile(agentName);
|
|
22
|
+
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
23
|
+
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
24
|
+
|
|
25
|
+
return new ImageResponse(
|
|
26
|
+
(
|
|
27
|
+
<div
|
|
28
|
+
style={{
|
|
29
|
+
width: '100%',
|
|
30
|
+
height: '100%',
|
|
31
|
+
backgroundColor: backgroundColor.toHex(),
|
|
32
|
+
color: agentColor.then(textColor).toHex(),
|
|
33
|
+
display: 'flex',
|
|
34
|
+
alignItems: 'center',
|
|
35
|
+
justifyContent: 'center',
|
|
36
|
+
}}
|
|
37
|
+
>
|
|
38
|
+
<div
|
|
39
|
+
style={{
|
|
40
|
+
width: '40%',
|
|
41
|
+
display: 'flex',
|
|
42
|
+
alignItems: 'center',
|
|
43
|
+
justifyContent: 'center',
|
|
44
|
+
}}
|
|
45
|
+
>
|
|
46
|
+
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
47
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
48
|
+
<img
|
|
49
|
+
style={{
|
|
50
|
+
width: '80%',
|
|
51
|
+
backgroundColor: agentColor.toHex(),
|
|
52
|
+
borderRadius: '50%',
|
|
53
|
+
}}
|
|
54
|
+
src={agentProfile.meta.image!}
|
|
55
|
+
alt="Agent Icon"
|
|
56
|
+
/>
|
|
57
|
+
</div>
|
|
58
|
+
<div style={{ width: '60%', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
|
|
59
|
+
<h1 style={{ fontSize: '110px' }}>{agentProfile.meta.fullname || agentName}</h1>
|
|
60
|
+
</div>
|
|
61
|
+
</div>
|
|
62
|
+
),
|
|
63
|
+
{
|
|
64
|
+
...size,
|
|
65
|
+
emoji: 'openmoji',
|
|
66
|
+
},
|
|
67
|
+
);
|
|
68
|
+
} catch (error) {
|
|
69
|
+
assertsError(error);
|
|
70
|
+
|
|
71
|
+
console.error(error);
|
|
72
|
+
|
|
73
|
+
return new Response(
|
|
74
|
+
JSON.stringify(
|
|
75
|
+
serializeError(error),
|
|
76
|
+
// <- TODO: [🐱🚀] Rename `serializeError` to `errorToJson`
|
|
77
|
+
null,
|
|
78
|
+
4,
|
|
79
|
+
// <- TODO: [🐱🚀] Allow to configure pretty print for agent server
|
|
80
|
+
),
|
|
81
|
+
{
|
|
82
|
+
status: 400, // <- TODO: [🐱🚀] Make `errorToHttpStatusCode`
|
|
83
|
+
headers: { 'Content-Type': 'application/json' },
|
|
84
|
+
},
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* TODO: [🦚] DRY
|
|
91
|
+
* TODO: [🦚] This should be the true screenshot NOT just image + Agent name
|
|
92
|
+
*/
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
4
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
5
|
+
import { PromptbookAgent } from '@promptbook-local/components';
|
|
6
|
+
import { parseAgentSource } from '@promptbook-local/core';
|
|
7
|
+
import { headers } from 'next/headers';
|
|
8
|
+
import spaceTrim from 'spacetrim';
|
|
9
|
+
import { $sideEffect } from '../../../../../../../src/utils/organization/$sideEffect';
|
|
10
|
+
import { CodePreview } from '../../../../../../_common/components/CodePreview/CodePreview';
|
|
11
|
+
import { generateAgentMetadata } from '../generateAgentMetadata';
|
|
12
|
+
|
|
13
|
+
export const generateMetadata = generateAgentMetadata;
|
|
14
|
+
|
|
15
|
+
export default async function AgentChatPage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
16
|
+
$sideEffect(headers());
|
|
17
|
+
let { agentName } = await params;
|
|
18
|
+
agentName = decodeURIComponent(agentName);
|
|
19
|
+
|
|
20
|
+
const collection = await $provideAgentCollectionForServer();
|
|
21
|
+
const agentSource = await collection.getAgentSource(agentName);
|
|
22
|
+
const { meta } = parseAgentSource(agentSource);
|
|
23
|
+
const { fullname, color, image, ...restMeta } = meta;
|
|
24
|
+
const { publicUrl } = await $provideServer();
|
|
25
|
+
const agentUrl = `${publicUrl.href}agents/${encodeURIComponent(agentName)}`;
|
|
26
|
+
|
|
27
|
+
const code = spaceTrim(
|
|
28
|
+
(block) => `
|
|
29
|
+
|
|
30
|
+
import { PromptbookAgent } from '@promptbook/components';
|
|
31
|
+
|
|
32
|
+
export function YourComponent() {
|
|
33
|
+
return(
|
|
34
|
+
<PromptbookAgent
|
|
35
|
+
agentUrl="${agentUrl}"
|
|
36
|
+
meta={${block(JSON.stringify({ fullname, color, image, ...restMeta }, null, 4))}}
|
|
37
|
+
/>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
`,
|
|
42
|
+
);
|
|
43
|
+
|
|
44
|
+
return (
|
|
45
|
+
<main className="w-screen h-screen p-4">
|
|
46
|
+
<h1 className="text-2xl font-bold p-4 border-b">{meta.fullname || agentName} Integration Code</h1>
|
|
47
|
+
<p className="mt-4 mb-8 text-gray-600">
|
|
48
|
+
Use the following code to integrate the <strong>{meta.fullname || agentName}</strong> agent into your
|
|
49
|
+
React application using the <code>{'<PromptbookAgent />'}</code> component.
|
|
50
|
+
</p>
|
|
51
|
+
|
|
52
|
+
<CodePreview code={code} />
|
|
53
|
+
<PromptbookAgent agentUrl={agentUrl} meta={meta} />
|
|
54
|
+
</main>
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* TODO: Make this page better, bring from Promptbook.Studio
|
|
60
|
+
* TODO: [🚗] Components and pages here should be just tiny UI wraper around proper agent logic and conponents
|
|
61
|
+
*/
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
|
+
import { serializeError } from '@promptbook-local/utils';
|
|
3
|
+
import { ImageResponse } from 'next/og';
|
|
4
|
+
import { assertsError } from '../../../../../../src/errors/assertsError';
|
|
5
|
+
import { Color } from '../../../../../../src/utils/color/Color';
|
|
6
|
+
import { textColor } from '../../../../../../src/utils/color/operators/furthest';
|
|
7
|
+
import { grayscale } from '../../../../../../src/utils/color/operators/grayscale';
|
|
8
|
+
import { getAgentName, getAgentProfile } from './_utils';
|
|
9
|
+
|
|
10
|
+
// export const runtime = 'edge';
|
|
11
|
+
// <- Note: On Vercel Edge runtime some modules are not working *(like `crypto`)*
|
|
12
|
+
|
|
13
|
+
export const alt = 'Agent Profile';
|
|
14
|
+
export const size = {
|
|
15
|
+
width: 1200,
|
|
16
|
+
height: 630,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
export const contentType = 'image/png';
|
|
20
|
+
|
|
21
|
+
export default async function Image({ params }: { params: Promise<{ agentName: string }> }) {
|
|
22
|
+
try {
|
|
23
|
+
const agentName = await getAgentName(params);
|
|
24
|
+
const agentProfile = await getAgentProfile(agentName);
|
|
25
|
+
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
26
|
+
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
27
|
+
|
|
28
|
+
return new ImageResponse(
|
|
29
|
+
(
|
|
30
|
+
<div
|
|
31
|
+
style={{
|
|
32
|
+
width: '100%',
|
|
33
|
+
height: '100%',
|
|
34
|
+
backgroundColor: backgroundColor.toHex(),
|
|
35
|
+
color: agentColor.then(textColor).toHex(),
|
|
36
|
+
display: 'flex',
|
|
37
|
+
alignItems: 'center',
|
|
38
|
+
justifyContent: 'center',
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<div
|
|
42
|
+
style={{
|
|
43
|
+
width: '50%',
|
|
44
|
+
display: 'flex',
|
|
45
|
+
alignItems: 'center',
|
|
46
|
+
justifyContent: 'center',
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
50
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
51
|
+
<img
|
|
52
|
+
style={{
|
|
53
|
+
width: '80%',
|
|
54
|
+
backgroundColor: agentColor.toHex(),
|
|
55
|
+
borderRadius: '50%',
|
|
56
|
+
}}
|
|
57
|
+
src={agentProfile.meta.image!}
|
|
58
|
+
alt="Agent Icon"
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
<div
|
|
62
|
+
style={{
|
|
63
|
+
width: '50%',
|
|
64
|
+
display: 'flex',
|
|
65
|
+
alignItems: 'center',
|
|
66
|
+
justifyContent: 'center',
|
|
67
|
+
textAlign: 'center',
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<h1 style={{ fontSize: '100px' }}>{agentProfile.meta.fullname || agentName}</h1>
|
|
71
|
+
</div>
|
|
72
|
+
</div>
|
|
73
|
+
),
|
|
74
|
+
{
|
|
75
|
+
...size,
|
|
76
|
+
emoji: 'openmoji',
|
|
77
|
+
},
|
|
78
|
+
);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
assertsError(error);
|
|
81
|
+
|
|
82
|
+
console.error(error);
|
|
83
|
+
|
|
84
|
+
return new Response(
|
|
85
|
+
JSON.stringify(
|
|
86
|
+
serializeError(error),
|
|
87
|
+
// <- TODO: [🐱🚀] Rename `serializeError` to `errorToJson`
|
|
88
|
+
null,
|
|
89
|
+
4,
|
|
90
|
+
// <- TODO: [🐱🚀] Allow to configure pretty print for agent server
|
|
91
|
+
),
|
|
92
|
+
{
|
|
93
|
+
status: 400, // <- TODO: [🐱🚀] Make `errorToHttpStatusCode`
|
|
94
|
+
headers: { 'Content-Type': 'application/json' },
|
|
95
|
+
},
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* TODO: [🦚] DRY
|
|
102
|
+
*/
|
|
@@ -1,19 +1,25 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
|
|
3
|
-
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
4
3
|
// import { BookEditor } from '@promptbook-local/components';
|
|
5
4
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
6
|
+
import { CodeIcon, HistoryIcon, NotebookPenIcon } from 'lucide-react';
|
|
8
7
|
import { headers } from 'next/headers';
|
|
9
8
|
import { notFound } from 'next/navigation';
|
|
10
9
|
import { Color } from '../../../../../../src/utils/color/Color';
|
|
11
10
|
import { withAlpha } from '../../../../../../src/utils/color/operators/withAlpha';
|
|
12
11
|
import { $sideEffect } from '../../../../../../src/utils/organization/$sideEffect';
|
|
12
|
+
import { AGENT_ACTIONS, getAgentName, getAgentProfile } from './_utils';
|
|
13
13
|
import { AgentChatWrapper } from './AgentChatWrapper';
|
|
14
14
|
import { AgentQrCode } from './AgentQrCode';
|
|
15
15
|
import { CopyField } from './CopyField';
|
|
16
16
|
import { generateAgentMetadata } from './generateAgentMetadata';
|
|
17
|
+
import { InstallPwaButton } from './InstallPwaButton';
|
|
18
|
+
import { ServiceWorkerRegister } from './ServiceWorkerRegister';
|
|
19
|
+
import { ClearAgentChatHistoryButton } from './ClearAgentChatHistoryButton';
|
|
20
|
+
import { ClearAgentChatFeedbackButton } from './ClearAgentChatFeedbackButton';
|
|
21
|
+
import { CloneAgentButton } from './CloneAgentButton';
|
|
22
|
+
import { isUserAdmin } from '../../../utils/isUserAdmin';
|
|
17
23
|
// import { Agent } from '@promptbook-local/core';
|
|
18
24
|
// import { RemoteLlmExecutionTools } from '@promptbook-local/remote-client';
|
|
19
25
|
// import { OpenAiAssistantExecutionTools } from '@promptbook-local/openai';
|
|
@@ -27,13 +33,12 @@ export default async function AgentPage({ params }: { params: Promise<{ agentNam
|
|
|
27
33
|
|
|
28
34
|
$sideEffect(headers());
|
|
29
35
|
|
|
30
|
-
|
|
31
|
-
|
|
36
|
+
const agentName = await getAgentName(params);
|
|
37
|
+
const isAdmin = await isUserAdmin();
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
let agentSource;
|
|
39
|
+
let agentProfile;
|
|
35
40
|
try {
|
|
36
|
-
|
|
41
|
+
agentProfile = await getAgentProfile(agentName);
|
|
37
42
|
} catch (error) {
|
|
38
43
|
if (
|
|
39
44
|
error instanceof Error &&
|
|
@@ -45,7 +50,6 @@ export default async function AgentPage({ params }: { params: Promise<{ agentNam
|
|
|
45
50
|
}
|
|
46
51
|
throw error;
|
|
47
52
|
}
|
|
48
|
-
const agentProfile = parseAgentSource(agentSource);
|
|
49
53
|
|
|
50
54
|
const { publicUrl } = await $provideServer();
|
|
51
55
|
|
|
@@ -58,13 +62,15 @@ export default async function AgentPage({ params }: { params: Promise<{ agentNam
|
|
|
58
62
|
console.log('[🐱🚀]', { pageUrl: agentUrl });
|
|
59
63
|
|
|
60
64
|
// Extract brand color from meta
|
|
61
|
-
const brandColor = Color.from(agentProfile.meta.color ||
|
|
65
|
+
const brandColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
62
66
|
|
|
63
67
|
// Mock agent actions
|
|
64
|
-
const agentActions =
|
|
68
|
+
const agentActions = AGENT_ACTIONS;
|
|
65
69
|
|
|
66
70
|
return (
|
|
67
71
|
<div className="flex flex-col md:flex-row h-[calc(100vh-60px)] w-full overflow-hidden">
|
|
72
|
+
<ServiceWorkerRegister scope={`/agents/${encodeURIComponent(agentName)}/`} />
|
|
73
|
+
|
|
68
74
|
{/* Left sidebar: Profile info */}
|
|
69
75
|
<div
|
|
70
76
|
className="w-full md:w-[400px] flex flex-col gap-6 p-6 overflow-y-auto border-r bg-gray-50 flex-shrink-0"
|
|
@@ -114,33 +120,46 @@ export default async function AgentPage({ params }: { params: Promise<{ agentNam
|
|
|
114
120
|
</div>
|
|
115
121
|
</div>
|
|
116
122
|
|
|
117
|
-
<div className="flex flex-col gap-
|
|
123
|
+
<div className="flex flex-col gap-3 mt-auto">
|
|
118
124
|
<div className="flex gap-2">
|
|
119
125
|
<a
|
|
120
|
-
href={`/agents/${encodeURIComponent(agentName)}/chat`}
|
|
126
|
+
href={`/agents/${encodeURIComponent(agentName)}/book+chat`}
|
|
121
127
|
// <- TODO: [🧠] Can I append path like this on current browser URL in href?
|
|
122
128
|
className="flex-1 inline-flex items-center justify-center whitespace-nowrap bg-white hover:bg-gray-100 text-gray-800 px-4 py-2 rounded shadow font-semibold transition border border-gray-200"
|
|
123
129
|
>
|
|
124
|
-
<
|
|
125
|
-
|
|
130
|
+
<NotebookPenIcon className="ml-2 w-4 h-4 mr-2" />
|
|
131
|
+
Edit
|
|
126
132
|
</a>
|
|
127
133
|
<a
|
|
128
|
-
href={`/agents/${encodeURIComponent(agentName)}/
|
|
134
|
+
href={`/agents/${encodeURIComponent(agentName)}/integration`}
|
|
129
135
|
// <- TODO: [🧠] Can I append path like this on current browser URL in href?
|
|
130
136
|
className="flex-1 inline-flex items-center justify-center whitespace-nowrap bg-white hover:bg-gray-100 text-gray-800 px-4 py-2 rounded shadow font-semibold transition border border-gray-200"
|
|
131
137
|
>
|
|
132
|
-
<
|
|
133
|
-
|
|
138
|
+
<CodeIcon className="ml-2 w-4 h-4 mr-2" />
|
|
139
|
+
Integration
|
|
134
140
|
</a>
|
|
135
141
|
<a
|
|
136
|
-
href={`/agents/${encodeURIComponent(agentName)}/
|
|
137
|
-
// <- TODO: [🧠] Can I append path like this on current browser URL in href?
|
|
142
|
+
href={`/agents/${encodeURIComponent(agentName)}/history`}
|
|
138
143
|
className="flex-1 inline-flex items-center justify-center whitespace-nowrap bg-white hover:bg-gray-100 text-gray-800 px-4 py-2 rounded shadow font-semibold transition border border-gray-200"
|
|
139
144
|
>
|
|
140
|
-
<
|
|
141
|
-
|
|
145
|
+
<HistoryIcon className="ml-2 w-4 h-4 mr-2" />
|
|
146
|
+
History
|
|
142
147
|
</a>
|
|
148
|
+
{isAdmin && <CloneAgentButton agentName={agentName} />}
|
|
149
|
+
<InstallPwaButton />
|
|
143
150
|
</div>
|
|
151
|
+
|
|
152
|
+
{isAdmin && (
|
|
153
|
+
<div className="border-t border-dashed border-gray-300 pt-3">
|
|
154
|
+
<h2 className="mb-2 text-xs font-semibold uppercase tracking-wide text-gray-600">
|
|
155
|
+
Maintenance
|
|
156
|
+
</h2>
|
|
157
|
+
<div className="flex flex-col gap-2">
|
|
158
|
+
<ClearAgentChatHistoryButton agentName={agentName} />
|
|
159
|
+
<ClearAgentChatFeedbackButton agentName={agentName} />
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
)}
|
|
144
163
|
</div>
|
|
145
164
|
|
|
146
165
|
<div className="flex flex-col items-center gap-4 pt-6 border-t border-gray-200 w-full">
|