@promptbook/cli 0.104.0-1 → 0.104.0-11
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/config.ts +1 -3
- package/apps/agents-server/next.config.ts +2 -2
- package/apps/agents-server/package.json +7 -3
- package/apps/agents-server/public/fonts/OpenMoji-color-cbdt.woff2 +0 -0
- package/apps/agents-server/public/swagger.json +115 -0
- package/apps/agents-server/scripts/generate-reserved-paths/generate-reserved-paths.ts +54 -0
- package/apps/agents-server/scripts/generate-reserved-paths/tsconfig.json +19 -0
- package/apps/agents-server/src/app/AddAgentButton.tsx +47 -21
- package/apps/agents-server/src/app/actions.ts +22 -5
- package/apps/agents-server/src/app/admin/browser-test/BrowserTestClient.tsx +211 -0
- package/apps/agents-server/src/app/admin/browser-test/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/chat-feedback/ChatFeedbackClient.tsx +221 -274
- package/apps/agents-server/src/app/admin/chat-history/ChatHistoryClient.tsx +94 -137
- package/apps/agents-server/src/app/admin/files/FilesGalleryClient.tsx +263 -0
- package/apps/agents-server/src/app/admin/files/actions.ts +61 -0
- package/apps/agents-server/src/app/admin/files/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/image-generator-test/ImageGeneratorTestClient.tsx +169 -0
- package/apps/agents-server/src/app/admin/image-generator-test/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/images/ImagesGalleryClient.tsx +256 -0
- package/apps/agents-server/src/app/admin/images/actions.ts +60 -0
- package/apps/agents-server/src/app/admin/images/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/messages/MessagesClient.tsx +294 -0
- package/apps/agents-server/src/app/admin/messages/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/messages/send-email/SendEmailClient.tsx +104 -0
- package/apps/agents-server/src/app/admin/messages/send-email/actions.ts +35 -0
- package/apps/agents-server/src/app/admin/messages/send-email/page.tsx +13 -0
- package/apps/agents-server/src/app/admin/metadata/MetadataClient.tsx +23 -19
- package/apps/agents-server/src/app/admin/search-engine-test/SearchEngineTestClient.tsx +109 -0
- package/apps/agents-server/src/app/admin/search-engine-test/actions.ts +17 -0
- package/apps/agents-server/src/app/admin/search-engine-test/page.tsx +13 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentChatWrapper.tsx +15 -1
- package/apps/agents-server/src/app/agents/[agentName]/AgentOptionsMenu.tsx +51 -9
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileChat.tsx +47 -4
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileWrapper.tsx +53 -11
- package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +23 -3
- package/apps/agents-server/src/app/agents/[agentName]/agentLinks.tsx +8 -8
- package/apps/agents-server/src/app/agents/[agentName]/api/agents/route.ts +17 -26
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +4 -2
- package/apps/agents-server/src/app/agents/[agentName]/api/chat/route.ts +20 -0
- package/apps/agents-server/src/app/agents/[agentName]/api/mcp/route.ts +6 -11
- package/apps/agents-server/src/app/agents/[agentName]/api/profile/route.ts +5 -1
- package/apps/agents-server/src/app/agents/[agentName]/api/voice/route.ts +5 -2
- package/apps/agents-server/src/app/agents/[agentName]/book/BookEditorWrapper.tsx +20 -16
- package/apps/agents-server/src/app/agents/[agentName]/book/page.tsx +15 -2
- package/apps/agents-server/src/app/agents/[agentName]/book+chat/page.tsx +15 -2
- package/apps/agents-server/src/app/agents/[agentName]/chat/page.tsx +12 -0
- package/apps/agents-server/src/app/agents/[agentName]/code/api/route.ts +68 -0
- package/apps/agents-server/src/app/agents/[agentName]/code/page.tsx +223 -0
- package/apps/agents-server/src/app/agents/[agentName]/generateAgentMetadata.ts +5 -0
- package/apps/agents-server/src/app/agents/[agentName]/history/actions.ts +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/history/page.tsx +10 -3
- package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/getAgentDefaultAvatarPrompt.ts +31 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/default-avatar.png/route.ts +194 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +14 -2
- package/apps/agents-server/src/app/agents/[agentName]/images/page.tsx +200 -0
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +4 -3
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +4 -3
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +10 -3
- package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +11 -4
- package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +11 -2
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +18 -10
- package/apps/agents-server/src/app/agents/[agentName]/system-message/page.tsx +100 -0
- package/apps/agents-server/src/app/api/admin-email/route.ts +12 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/clone/route.ts +13 -14
- package/apps/agents-server/src/app/api/agents/[agentName]/restore/route.ts +20 -0
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +43 -1
- package/apps/agents-server/src/app/api/agents/route.ts +28 -3
- package/apps/agents-server/src/app/api/api-tokens/route.ts +6 -7
- package/apps/agents-server/src/app/api/browser-test/act/route.ts +141 -0
- package/apps/agents-server/src/app/api/browser-test/screenshot/route.ts +30 -0
- package/apps/agents-server/src/app/api/browser-test/scroll-facebook/route.ts +62 -0
- package/apps/agents-server/src/app/api/docs/book.md/route.ts +61 -0
- package/apps/agents-server/src/app/api/emails/incoming/sendgrid/route.ts +48 -0
- package/apps/agents-server/src/app/api/federated-agents/route.ts +12 -0
- package/apps/agents-server/src/app/api/images/[filename]/route.ts +128 -0
- package/apps/agents-server/src/app/api/messages/route.ts +102 -0
- package/apps/agents-server/src/app/api/metadata/route.ts +5 -6
- package/apps/agents-server/src/app/api/upload/route.ts +128 -45
- package/apps/agents-server/src/app/docs/[docId]/page.tsx +2 -3
- package/apps/agents-server/src/app/docs/page.tsx +12 -12
- package/apps/agents-server/src/app/globals.css +140 -33
- package/apps/agents-server/src/app/humans.txt/route.ts +1 -1
- package/apps/agents-server/src/app/layout.tsx +27 -22
- package/apps/agents-server/src/app/page.tsx +54 -6
- package/apps/agents-server/src/app/recycle-bin/actions.ts +20 -14
- package/apps/agents-server/src/app/recycle-bin/page.tsx +27 -41
- package/apps/agents-server/src/app/robots.txt/route.ts +1 -1
- package/apps/agents-server/src/app/security.txt/route.ts +1 -1
- package/apps/agents-server/src/app/sitemap.xml/route.ts +9 -7
- package/apps/agents-server/src/app/swagger/page.tsx +14 -0
- package/apps/agents-server/src/components/AgentProfile/AgentCapabilityChips.tsx +38 -0
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +44 -116
- package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +92 -0
- package/apps/agents-server/src/components/AgentProfile/QrCodeModal.tsx +0 -1
- package/apps/agents-server/src/components/AgentProfile/useAgentBackground.ts +97 -0
- package/apps/agents-server/src/components/Auth/AuthControls.tsx +5 -4
- package/apps/agents-server/src/components/DeletedAgentBanner.tsx +26 -0
- package/apps/agents-server/src/components/DocsToolbar/DocsToolbar.tsx +38 -0
- package/apps/agents-server/src/components/DocumentationContent/DocumentationContent.tsx +11 -9
- package/apps/agents-server/src/components/Footer/Footer.tsx +5 -5
- package/apps/agents-server/src/components/ForgottenPasswordDialog/ForgottenPasswordDialog.tsx +61 -0
- package/apps/agents-server/src/components/Header/Header.tsx +130 -40
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +150 -23
- package/apps/agents-server/src/components/Homepage/AgentsList.tsx +93 -15
- package/apps/agents-server/src/components/Homepage/DeletedAgentsList.tsx +66 -0
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSection.tsx +12 -3
- package/apps/agents-server/src/components/Homepage/ExternalAgentsSectionClient.tsx +19 -10
- package/apps/agents-server/src/components/LayoutWrapper/LayoutWrapper.tsx +3 -2
- package/apps/agents-server/src/components/LoginForm/LoginForm.tsx +50 -1
- package/apps/agents-server/src/components/NewAgentDialog/NewAgentDialog.tsx +88 -0
- package/apps/agents-server/src/components/NotFoundPage/NotFoundPage.tsx +7 -2
- package/apps/agents-server/src/components/OpenMojiIcon/OpenMojiIcon.tsx +16 -7
- package/apps/agents-server/src/components/PrintHeader/PrintHeader.tsx +4 -4
- package/apps/agents-server/src/components/RegisterUserDialog/RegisterUserDialog.tsx +61 -0
- package/apps/agents-server/src/components/VercelDeploymentCard/VercelDeploymentCard.tsx +2 -0
- package/apps/agents-server/src/components/_utils/generateMetaTxt.ts +12 -10
- package/apps/agents-server/src/components/_utils/headlessParam.tsx +7 -3
- package/apps/agents-server/src/database/$getTableName.ts +1 -0
- package/apps/agents-server/src/database/$provideSupabaseForBrowser.ts +3 -3
- package/apps/agents-server/src/database/$provideSupabaseForServer.ts +1 -1
- package/apps/agents-server/src/database/$provideSupabaseForWorker.ts +3 -3
- package/apps/agents-server/src/database/metadataDefaults.ts +19 -1
- package/apps/agents-server/src/database/migrate.ts +34 -1
- package/apps/agents-server/src/database/migrations/2025-11-0001-initial-schema.sql +1 -3
- package/apps/agents-server/src/database/migrations/2025-11-0002-metadata-table.sql +1 -3
- package/apps/agents-server/src/database/migrations/2025-12-0240-agent-public-id.sql +3 -0
- package/apps/agents-server/src/database/migrations/2025-12-0360-agent-deleted-at.sql +1 -0
- package/apps/agents-server/src/database/migrations/2025-12-0370-image-table.sql +19 -0
- package/apps/agents-server/src/database/migrations/2025-12-0380-agent-visibility.sql +1 -0
- package/apps/agents-server/src/database/migrations/2025-12-0390-upload-tracking.sql +20 -0
- package/apps/agents-server/src/database/migrations/2025-12-0401-file-upload-status.sql +13 -0
- package/apps/agents-server/src/database/migrations/2025-12-0402-message-table.sql +42 -0
- package/apps/agents-server/src/database/migrations/2025-12-0403-generation-lock-table.sql +15 -0
- package/apps/agents-server/src/database/migrations/2025-12-0640-openai-assistant-cache.sql +12 -0
- package/apps/agents-server/src/database/migrations/2025-12-0820-agent-history-permanent-id.sql +29 -0
- package/apps/agents-server/src/database/migrations/2025-12-0830-image-purpose.sql +5 -0
- package/apps/agents-server/src/database/migrations/2025-12-0890-file-agent-id.sql +5 -0
- package/apps/agents-server/src/database/schema.ts +244 -4
- package/apps/agents-server/src/generated/reservedPaths.ts +32 -0
- package/apps/agents-server/src/message-providers/email/_common/Email.ts +73 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/TODO.txt +1 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.test.ts.todo +108 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddress.ts +62 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.test.ts.todo +117 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/parseEmailAddresses.ts +19 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.test.ts.todo +119 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddress.ts +19 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.test.ts.todo +74 -0
- package/apps/agents-server/src/message-providers/email/_common/utils/stringifyEmailAddresses.ts +14 -0
- package/apps/agents-server/src/message-providers/email/sendgrid/SendgridMessageProvider.ts +44 -0
- package/apps/agents-server/src/message-providers/email/sendgrid/parseInboundSendgridEmail.ts +49 -0
- package/apps/agents-server/src/message-providers/email/zeptomail/ZeptomailMessageProvider.ts +51 -0
- package/apps/agents-server/src/message-providers/index.ts +13 -0
- package/apps/agents-server/src/message-providers/interfaces/MessageProvider.ts +11 -0
- package/apps/agents-server/src/middleware.ts +19 -23
- package/apps/agents-server/src/tools/$provideBrowserForServer.ts +32 -0
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +7 -2
- package/apps/agents-server/src/utils/auth.ts +117 -17
- package/apps/agents-server/src/utils/cdn/classes/TrackedFilesStorage.ts +57 -0
- package/apps/agents-server/src/utils/cdn/classes/VercelBlobStorage.ts +4 -0
- package/apps/agents-server/src/utils/cdn/interfaces/IFilesStorage.ts +18 -0
- package/apps/agents-server/src/utils/content/extractBodyContentFromHtml.ts +19 -0
- package/apps/agents-server/src/utils/getUserIdFromRequest.ts +35 -0
- package/apps/agents-server/src/utils/handleChatCompletion.ts +65 -5
- package/apps/agents-server/src/utils/messages/sendMessage.ts +91 -0
- package/apps/agents-server/src/utils/messagesAdmin.ts +72 -0
- package/apps/agents-server/src/utils/normalization/filenameToPrompt.test.ts +36 -0
- package/apps/agents-server/src/utils/normalization/filenameToPrompt.ts +25 -0
- package/apps/agents-server/src/utils/validateApiKey.ts +7 -11
- package/esm/index.es.js +1534 -1330
- package/esm/index.es.js.map +1 -1
- package/esm/typings/servers.d.ts +8 -0
- package/esm/typings/src/_packages/core.index.d.ts +2 -0
- package/esm/typings/src/_packages/types.index.d.ts +16 -2
- package/esm/typings/src/book-2.0/agent-source/AgentBasicInformation.d.ts +29 -1
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.d.ts +6 -6
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirementsWithCommitments.closed.test.d.ts +1 -0
- package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +3 -3
- package/esm/typings/src/book-components/Chat/Chat/ChatMessageItem.d.ts +5 -1
- package/esm/typings/src/book-components/Chat/Chat/ChatProps.d.ts +5 -0
- package/esm/typings/src/book-components/Chat/CodeBlock/CodeBlock.d.ts +13 -0
- package/esm/typings/src/book-components/Chat/MarkdownContent/MarkdownContent.d.ts +1 -0
- package/esm/typings/src/book-components/Chat/types/ChatMessage.d.ts +9 -13
- package/esm/typings/src/book-components/_common/Dropdown/Dropdown.d.ts +3 -3
- package/esm/typings/src/book-components/_common/HamburgerMenu/HamburgerMenu.d.ts +1 -1
- package/esm/typings/src/book-components/_common/MenuHoisting/MenuHoistingContext.d.ts +56 -0
- package/esm/typings/src/book-components/icons/AboutIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/AttachmentIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/CameraIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/DownloadIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/MenuIcon.d.ts +1 -1
- package/esm/typings/src/book-components/icons/SaveIcon.d.ts +1 -1
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +22 -12
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +27 -15
- package/esm/typings/src/commitments/DICTIONARY/DICTIONARY.d.ts +46 -0
- package/esm/typings/src/commitments/index.d.ts +2 -1
- package/esm/typings/src/llm-providers/_common/utils/count-total-usage/countUsage.d.ts +1 -1
- package/esm/typings/src/llm-providers/_multiple/MultipleLlmExecutionTools.d.ts +6 -2
- package/esm/typings/src/llm-providers/agent/Agent.d.ts +6 -1
- package/esm/typings/src/llm-providers/agent/AgentLlmExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/ollama/OllamaExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/openai/createOpenAiCompatibleExecutionTools.d.ts +1 -1
- package/esm/typings/src/llm-providers/remote/RemoteLlmExecutionTools.d.ts +1 -0
- package/esm/typings/src/remote-server/ui/ServerApp.d.ts +1 -1
- package/esm/typings/src/search-engines/SearchEngine.d.ts +9 -0
- package/esm/typings/src/search-engines/SearchResult.d.ts +18 -0
- package/esm/typings/src/search-engines/bing/BingSearchEngine.d.ts +15 -0
- package/esm/typings/src/search-engines/dummy/DummySearchEngine.d.ts +15 -0
- package/esm/typings/src/types/Message.d.ts +49 -0
- package/esm/typings/src/types/ModelRequirements.d.ts +38 -14
- package/esm/typings/src/types/typeAliases.d.ts +23 -1
- package/esm/typings/src/utils/color/utils/colorToDataUrl.d.ts +2 -1
- package/esm/typings/src/utils/environment/$detectRuntimeEnvironment.d.ts +4 -4
- package/esm/typings/src/utils/environment/$isRunningInBrowser.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInJest.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInNode.d.ts +1 -1
- package/esm/typings/src/utils/environment/$isRunningInWebWorker.d.ts +1 -1
- package/esm/typings/src/utils/markdown/extractAllBlocksFromMarkdown.d.ts +2 -2
- package/esm/typings/src/utils/markdown/extractOneBlockFromMarkdown.d.ts +2 -2
- package/esm/typings/src/utils/random/$randomAgentPersona.d.ts +3 -2
- package/esm/typings/src/utils/random/$randomBase58.d.ts +12 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +1542 -1338
- package/umd/index.umd.js.map +1 -1
- package/apps/agents-server/package-lock.json +0 -27
- package/apps/agents-server/public/fonts/download-font.js +0 -22
- package/apps/agents-server/src/components/PrintButton/PrintButton.tsx +0 -18
- package/esm/typings/src/book-2.0/utils/generateGravatarUrl.d.ts +0 -10
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import { $getTableName } from '@/src/database/$getTableName';
|
|
2
|
+
import { $provideSupabaseForServer } from '@/src/database/$provideSupabaseForServer';
|
|
3
|
+
import { $provideAgentCollectionForServer } from '@/src/tools/$provideAgentCollectionForServer';
|
|
4
|
+
import { $provideCdnForServer } from '@/src/tools/$provideCdnForServer';
|
|
5
|
+
import { $provideExecutionToolsForServer } from '@/src/tools/$provideExecutionToolsForServer';
|
|
6
|
+
import { parseAgentSource } from '@promptbook-local/core';
|
|
7
|
+
import { computeHash, serializeError } from '@promptbook-local/utils';
|
|
8
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
9
|
+
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
10
|
+
import type { LlmExecutionTools } from '../../../../../../../../src/execution/LlmExecutionTools';
|
|
11
|
+
import { getSingleLlmExecutionTools } from '../../../../../../../../src/llm-providers/_multiple/getSingleLlmExecutionTools';
|
|
12
|
+
import type { string_url } from '../../../../../../../../src/types/typeAliases';
|
|
13
|
+
import { getAgentDefaultAvatarPrompt } from './getAgentDefaultAvatarPrompt';
|
|
14
|
+
|
|
15
|
+
export async function GET(request: NextRequest, { params }: { params: Promise<{ agentName: string }> }) {
|
|
16
|
+
try {
|
|
17
|
+
let { agentName } = await params;
|
|
18
|
+
agentName = decodeURIComponent(agentName);
|
|
19
|
+
|
|
20
|
+
if (!agentName) {
|
|
21
|
+
return NextResponse.json({ error: 'Agent name is required' }, { status: 400 });
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// 1. Fetch agent data first to construct the prompt
|
|
25
|
+
const collection = await $provideAgentCollectionForServer();
|
|
26
|
+
let agentSource;
|
|
27
|
+
try {
|
|
28
|
+
agentSource = await collection.getAgentSource(agentName);
|
|
29
|
+
} catch (error) {
|
|
30
|
+
assertsError(error);
|
|
31
|
+
|
|
32
|
+
return NextResponse.json({ error: serializeError(error) }, { status: 500 });
|
|
33
|
+
|
|
34
|
+
//> // If agent not found, redirect to pravatar with the agent name as unique identifier
|
|
35
|
+
//> const pravaratUrl = `https://i.pravatar.cc/1024?u=${encodeURIComponent(agentName)}`;
|
|
36
|
+
//> return NextResponse.redirect(pravaratUrl);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const agentProfile = parseAgentSource(agentSource);
|
|
40
|
+
|
|
41
|
+
const prompt = getAgentDefaultAvatarPrompt(agentProfile);
|
|
42
|
+
|
|
43
|
+
// Use hash of the prompt as cache key - this ensures regeneration when prompt changes
|
|
44
|
+
const promptHash = computeHash(prompt);
|
|
45
|
+
const internalFilename = `agent-avatar-${promptHash}.png`;
|
|
46
|
+
|
|
47
|
+
const supabase = $provideSupabaseForServer();
|
|
48
|
+
const lockKey = `agent-avatar-${promptHash}`;
|
|
49
|
+
|
|
50
|
+
// Loop to acquire lock or wait for image
|
|
51
|
+
// We try for 60 seconds
|
|
52
|
+
for (let attempt = 0; attempt < 60; attempt++) {
|
|
53
|
+
// 1. Check if image with this prompt hash already exists in database
|
|
54
|
+
const { data: existingImage, error: selectError } = await supabase
|
|
55
|
+
.from(await $getTableName(`Image`))
|
|
56
|
+
.select('cdnUrl')
|
|
57
|
+
.eq('filename', internalFilename)
|
|
58
|
+
.single();
|
|
59
|
+
|
|
60
|
+
if (selectError && selectError.code !== 'PGRST116') {
|
|
61
|
+
// PGRST116 is "not found"
|
|
62
|
+
throw selectError;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (existingImage) {
|
|
66
|
+
// Image exists, fetch from CDN and return directly
|
|
67
|
+
const imageResponse = await fetch(existingImage.cdnUrl as string_url);
|
|
68
|
+
if (!imageResponse.ok) {
|
|
69
|
+
console.warn(`Failed to fetch image from CDN: ${imageResponse.status}`);
|
|
70
|
+
return NextResponse.redirect(existingImage.cdnUrl);
|
|
71
|
+
}
|
|
72
|
+
const imageBuffer = await imageResponse.arrayBuffer();
|
|
73
|
+
return new NextResponse(imageBuffer, {
|
|
74
|
+
status: 200,
|
|
75
|
+
headers: {
|
|
76
|
+
'Content-Type': 'image/png',
|
|
77
|
+
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 2. Try to acquire lock to generate it
|
|
83
|
+
const { error: lockError } = await supabase.from(await $getTableName('GenerationLock')).insert({
|
|
84
|
+
lockKey,
|
|
85
|
+
expiresAt: new Date(Date.now() + 1000 * 60 * 5).toISOString(), // 5 minutes
|
|
86
|
+
});
|
|
87
|
+
|
|
88
|
+
if (!lockError) {
|
|
89
|
+
// Lock acquired!
|
|
90
|
+
try {
|
|
91
|
+
// 2. Generate image
|
|
92
|
+
const executionTools = await $provideExecutionToolsForServer();
|
|
93
|
+
const llmTools = getSingleLlmExecutionTools(executionTools.llm) as LlmExecutionTools;
|
|
94
|
+
|
|
95
|
+
if (!llmTools.callImageGenerationModel) {
|
|
96
|
+
throw new Error('Image generation is not supported by the current LLM configuration');
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
const imageResult = await llmTools.callImageGenerationModel({
|
|
100
|
+
title: `Generate default avatar for ${agentName}`,
|
|
101
|
+
content: prompt,
|
|
102
|
+
parameters: {},
|
|
103
|
+
modelRequirements: {
|
|
104
|
+
modelVariant: 'IMAGE_GENERATION',
|
|
105
|
+
modelName: 'dall-e-3',
|
|
106
|
+
size: '1024x1792', // <- Vertical orientation
|
|
107
|
+
// <- TODO: [🤐] DRY
|
|
108
|
+
quality: 'hd',
|
|
109
|
+
style: 'natural',
|
|
110
|
+
},
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
if (!imageResult.content) {
|
|
114
|
+
throw new Error('Failed to generate image: no content returned');
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// 3. Download and Upload to CDN
|
|
118
|
+
const imageResponse = await fetch(imageResult.content);
|
|
119
|
+
if (!imageResponse.ok) {
|
|
120
|
+
throw new Error(`Failed to download generated image: ${imageResponse.status}`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const imageBuffer = await imageResponse.arrayBuffer();
|
|
124
|
+
const buffer = Buffer.from(imageBuffer);
|
|
125
|
+
|
|
126
|
+
const cdn = $provideCdnForServer();
|
|
127
|
+
const cdnKey = `generated-images/${internalFilename}`;
|
|
128
|
+
await cdn.setItem(cdnKey, {
|
|
129
|
+
type: 'image/png',
|
|
130
|
+
data: buffer,
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
const cdnUrl = cdn.getItemUrl(cdnKey);
|
|
134
|
+
|
|
135
|
+
// 4. Save to database
|
|
136
|
+
const { error: insertError } = await supabase.from(await $getTableName(`Image`)).insert({
|
|
137
|
+
filename: internalFilename,
|
|
138
|
+
prompt,
|
|
139
|
+
cdnUrl: cdnUrl.href,
|
|
140
|
+
cdnKey,
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
if (insertError) {
|
|
144
|
+
throw insertError;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Return the newly created image directly
|
|
148
|
+
const finalImageResponse = await fetch(cdnUrl.href);
|
|
149
|
+
if (!finalImageResponse.ok) {
|
|
150
|
+
console.warn(`Failed to fetch newly created image from CDN: ${finalImageResponse.status}`);
|
|
151
|
+
return NextResponse.redirect(cdnUrl.href);
|
|
152
|
+
}
|
|
153
|
+
const finalImageBuffer = await finalImageResponse.arrayBuffer();
|
|
154
|
+
return new NextResponse(finalImageBuffer, {
|
|
155
|
+
status: 200,
|
|
156
|
+
headers: {
|
|
157
|
+
'Content-Type': 'image/png',
|
|
158
|
+
'Cache-Control': 'public, max-age=31536000, immutable',
|
|
159
|
+
},
|
|
160
|
+
});
|
|
161
|
+
} finally {
|
|
162
|
+
// Release lock
|
|
163
|
+
await supabase.from(await $getTableName('GenerationLock')).delete().eq('lockKey', lockKey);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// Lock failed, someone else is generating
|
|
168
|
+
// Check if expired
|
|
169
|
+
const { data: lockData } = await supabase
|
|
170
|
+
.from(await $getTableName('GenerationLock'))
|
|
171
|
+
.select('expiresAt')
|
|
172
|
+
.eq('lockKey', lockKey)
|
|
173
|
+
.single();
|
|
174
|
+
|
|
175
|
+
if (lockData && new Date(lockData.expiresAt) < new Date()) {
|
|
176
|
+
// Expired, delete and retry loop immediately
|
|
177
|
+
await supabase.from(await $getTableName('GenerationLock')).delete().eq('lockKey', lockKey);
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Wait and retry
|
|
182
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
throw new Error('Timeout waiting for image generation');
|
|
186
|
+
} catch (error) {
|
|
187
|
+
assertsError(error);
|
|
188
|
+
console.error('Error serving default avatar:', error);
|
|
189
|
+
return new Response(JSON.stringify(serializeError(error), null, 4), {
|
|
190
|
+
status: 500,
|
|
191
|
+
headers: { 'Content-Type': 'application/json' },
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
2
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
3
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
4
|
import { ImageResponse } from 'next/og';
|
|
4
5
|
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
@@ -18,6 +19,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
18
19
|
const agentName = await getAgentName(params);
|
|
19
20
|
const agentProfile = await getAgentProfile(agentName);
|
|
20
21
|
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
22
|
+
const { publicUrl } = await $provideServer();
|
|
21
23
|
|
|
22
24
|
return new ImageResponse(
|
|
23
25
|
(
|
|
@@ -30,6 +32,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
30
32
|
alignItems: 'center',
|
|
31
33
|
justifyContent: 'center',
|
|
32
34
|
borderRadius: '50%',
|
|
35
|
+
aspectRatio: '1 / 1',
|
|
33
36
|
overflow: 'hidden',
|
|
34
37
|
}}
|
|
35
38
|
>
|
|
@@ -45,7 +48,16 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
45
48
|
>
|
|
46
49
|
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
47
50
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
48
|
-
<img
|
|
51
|
+
<img
|
|
52
|
+
src={
|
|
53
|
+
agentProfile.meta.image ||
|
|
54
|
+
generatePlaceholderAgentProfileImageUrl(
|
|
55
|
+
agentProfile.permanentId || agentName,
|
|
56
|
+
publicUrl,
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
alt="Agent Icon"
|
|
60
|
+
/>
|
|
49
61
|
</div>
|
|
50
62
|
</div>
|
|
51
63
|
),
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
'use server';
|
|
2
|
+
|
|
3
|
+
import { saturate } from '@promptbook-local/color';
|
|
4
|
+
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
5
|
+
import Link from 'next/link';
|
|
6
|
+
import { Color } from '../../../../../../../src/utils/color/Color';
|
|
7
|
+
import { getAgentName, getAgentProfile } from '../_utils';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Available image types for agents with their descriptions and sizes
|
|
11
|
+
*/
|
|
12
|
+
const AGENT_IMAGES = [
|
|
13
|
+
{
|
|
14
|
+
name: 'default-avatar.png',
|
|
15
|
+
title: 'Default Avatar',
|
|
16
|
+
description: 'AI-generated avatar image based on the agent profile. Vertical orientation (1024x1792).',
|
|
17
|
+
size: '1024×1792',
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'icon-256.png',
|
|
21
|
+
title: 'Icon (256×256)',
|
|
22
|
+
description: 'Small circular icon suitable for profile pictures and thumbnails.',
|
|
23
|
+
size: '256×256',
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'screenshot-fullhd.png',
|
|
27
|
+
title: 'Screenshot Full HD',
|
|
28
|
+
description: 'Landscape screenshot showing the agent with name. Suitable for desktop previews.',
|
|
29
|
+
size: '1920×1080',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'screenshot-phone.png',
|
|
33
|
+
title: 'Screenshot Phone',
|
|
34
|
+
description: 'Portrait screenshot optimized for mobile devices.',
|
|
35
|
+
size: '1080×1920',
|
|
36
|
+
},
|
|
37
|
+
] as const;
|
|
38
|
+
|
|
39
|
+
export default async function AgentImagesPage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
40
|
+
const agentName = await getAgentName(params);
|
|
41
|
+
const agentProfile = await getAgentProfile(agentName);
|
|
42
|
+
|
|
43
|
+
const brandColor = Color.fromSafe(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
44
|
+
const brandColorHex = brandColor.then(saturate(-0.5)).toHex();
|
|
45
|
+
|
|
46
|
+
const fullname = (agentProfile.meta.fullname || agentProfile.agentName || 'Agent') as string;
|
|
47
|
+
|
|
48
|
+
return (
|
|
49
|
+
<div
|
|
50
|
+
style={{
|
|
51
|
+
minHeight: '100vh',
|
|
52
|
+
backgroundColor: '#f5f5f5',
|
|
53
|
+
padding: '2rem',
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
<div
|
|
57
|
+
style={{
|
|
58
|
+
maxWidth: '1200px',
|
|
59
|
+
margin: '0 auto',
|
|
60
|
+
}}
|
|
61
|
+
>
|
|
62
|
+
<header
|
|
63
|
+
style={{
|
|
64
|
+
marginBottom: '2rem',
|
|
65
|
+
padding: '1.5rem',
|
|
66
|
+
backgroundColor: brandColorHex,
|
|
67
|
+
borderRadius: '12px',
|
|
68
|
+
color: 'white',
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<h1 style={{ margin: 0, fontSize: '2rem' }}>
|
|
72
|
+
Images for <strong>{fullname}</strong>
|
|
73
|
+
</h1>
|
|
74
|
+
<p style={{ margin: '0.5rem 0 0', opacity: 0.9 }}>
|
|
75
|
+
All available image assets for agent{' '}
|
|
76
|
+
<code
|
|
77
|
+
style={{
|
|
78
|
+
backgroundColor: 'rgba(255,255,255,0.2)',
|
|
79
|
+
padding: '2px 6px',
|
|
80
|
+
borderRadius: '4px',
|
|
81
|
+
}}
|
|
82
|
+
>
|
|
83
|
+
{agentName}
|
|
84
|
+
</code>
|
|
85
|
+
</p>
|
|
86
|
+
</header>
|
|
87
|
+
|
|
88
|
+
<div
|
|
89
|
+
style={{
|
|
90
|
+
display: 'grid',
|
|
91
|
+
gridTemplateColumns: 'repeat(auto-fill, minmax(300px, 1fr))',
|
|
92
|
+
gap: '1.5rem',
|
|
93
|
+
}}
|
|
94
|
+
>
|
|
95
|
+
{AGENT_IMAGES.map((image) => {
|
|
96
|
+
const imageUrl = `/agents/${encodeURIComponent(agentName)}/images/${image.name}`;
|
|
97
|
+
return (
|
|
98
|
+
<div
|
|
99
|
+
key={image.name}
|
|
100
|
+
style={{
|
|
101
|
+
backgroundColor: 'white',
|
|
102
|
+
borderRadius: '12px',
|
|
103
|
+
overflow: 'hidden',
|
|
104
|
+
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
105
|
+
}}
|
|
106
|
+
>
|
|
107
|
+
<div
|
|
108
|
+
style={{
|
|
109
|
+
aspectRatio: '16/9',
|
|
110
|
+
backgroundColor: '#e0e0e0',
|
|
111
|
+
display: 'flex',
|
|
112
|
+
alignItems: 'center',
|
|
113
|
+
justifyContent: 'center',
|
|
114
|
+
overflow: 'hidden',
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
118
|
+
<img
|
|
119
|
+
src={imageUrl}
|
|
120
|
+
alt={image.title}
|
|
121
|
+
style={{
|
|
122
|
+
maxWidth: '100%',
|
|
123
|
+
maxHeight: '100%',
|
|
124
|
+
objectFit: 'contain',
|
|
125
|
+
}}
|
|
126
|
+
/>
|
|
127
|
+
</div>
|
|
128
|
+
<div style={{ padding: '1rem' }}>
|
|
129
|
+
<h2 style={{ margin: '0 0 0.5rem', fontSize: '1.25rem' }}>{image.title}</h2>
|
|
130
|
+
<p style={{ margin: '0 0 0.5rem', color: '#666', fontSize: '0.9rem' }}>
|
|
131
|
+
{image.description}
|
|
132
|
+
</p>
|
|
133
|
+
<div
|
|
134
|
+
style={{
|
|
135
|
+
display: 'flex',
|
|
136
|
+
justifyContent: 'space-between',
|
|
137
|
+
alignItems: 'center',
|
|
138
|
+
marginTop: '1rem',
|
|
139
|
+
}}
|
|
140
|
+
>
|
|
141
|
+
<span
|
|
142
|
+
style={{
|
|
143
|
+
backgroundColor: '#f0f0f0',
|
|
144
|
+
padding: '4px 8px',
|
|
145
|
+
borderRadius: '4px',
|
|
146
|
+
fontSize: '0.85rem',
|
|
147
|
+
color: '#555',
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
{image.size}
|
|
151
|
+
</span>
|
|
152
|
+
<Link
|
|
153
|
+
href={imageUrl}
|
|
154
|
+
target="_blank"
|
|
155
|
+
style={{
|
|
156
|
+
backgroundColor: brandColorHex,
|
|
157
|
+
color: 'white',
|
|
158
|
+
padding: '8px 16px',
|
|
159
|
+
borderRadius: '6px',
|
|
160
|
+
textDecoration: 'none',
|
|
161
|
+
fontSize: '0.9rem',
|
|
162
|
+
}}
|
|
163
|
+
>
|
|
164
|
+
Open Image
|
|
165
|
+
</Link>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
);
|
|
170
|
+
})}
|
|
171
|
+
</div>
|
|
172
|
+
|
|
173
|
+
<footer
|
|
174
|
+
style={{
|
|
175
|
+
marginTop: '2rem',
|
|
176
|
+
padding: '1rem',
|
|
177
|
+
backgroundColor: 'white',
|
|
178
|
+
borderRadius: '12px',
|
|
179
|
+
textAlign: 'center',
|
|
180
|
+
color: '#666',
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
<p style={{ margin: 0 }}>
|
|
184
|
+
<Link
|
|
185
|
+
href={`/agents/${encodeURIComponent(agentName)}`}
|
|
186
|
+
style={{ color: brandColorHex, textDecoration: 'none' }}
|
|
187
|
+
>
|
|
188
|
+
← Back to {fullname}
|
|
189
|
+
</Link>
|
|
190
|
+
</p>
|
|
191
|
+
</footer>
|
|
192
|
+
</div>
|
|
193
|
+
</div>
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* TODO: [🦚] Add download button functionality
|
|
199
|
+
* TODO: [🦚] Add image regeneration option for default-avatar
|
|
200
|
+
*/
|
package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
1
2
|
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
3
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
4
|
import { ImageResponse } from 'next/og';
|
|
@@ -21,6 +22,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
21
22
|
const agentProfile = await getAgentProfile(agentName);
|
|
22
23
|
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
23
24
|
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
25
|
+
const { publicUrl } = await $provideServer();
|
|
24
26
|
|
|
25
27
|
return new ImageResponse(
|
|
26
28
|
(
|
|
@@ -48,10 +50,9 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
48
50
|
<img
|
|
49
51
|
style={{
|
|
50
52
|
width: '80%',
|
|
51
|
-
backgroundColor: agentColor.toHex(),
|
|
52
|
-
borderRadius: '50%',
|
|
53
|
+
// backgroundColor: agentColor.toHex(),
|
|
53
54
|
}}
|
|
54
|
-
src={agentProfile.
|
|
55
|
+
src={`${publicUrl.href}agents/${agentProfile.permanentId || agentName}/images/icon-256.png`}
|
|
55
56
|
alt="Agent Icon"
|
|
56
57
|
/>
|
|
57
58
|
</div>
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
1
2
|
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
3
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
4
|
import { ImageResponse } from 'next/og';
|
|
@@ -21,6 +22,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
21
22
|
const agentProfile = await getAgentProfile(agentName);
|
|
22
23
|
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
23
24
|
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
25
|
+
const { publicUrl } = await $provideServer();
|
|
24
26
|
|
|
25
27
|
return new ImageResponse(
|
|
26
28
|
(
|
|
@@ -48,10 +50,9 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
48
50
|
<img
|
|
49
51
|
style={{
|
|
50
52
|
width: '80%',
|
|
51
|
-
backgroundColor: agentColor.toHex(),
|
|
52
|
-
borderRadius: '50%',
|
|
53
|
+
// backgroundColor: agentColor.toHex(),
|
|
53
54
|
}}
|
|
54
|
-
src={agentProfile.
|
|
55
|
+
src={`${publicUrl.href}agents/${agentProfile.permanentId || agentName}/images/icon-256.png`}
|
|
55
56
|
alt="Agent Icon"
|
|
56
57
|
/>
|
|
57
58
|
</div>
|
|
@@ -4,7 +4,7 @@ import { $getTableName } from '@/src/database/$getTableName';
|
|
|
4
4
|
import { $provideSupabase } from '@/src/database/$provideSupabase';
|
|
5
5
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
6
6
|
import { isUserAdmin } from '@/src/utils/isUserAdmin';
|
|
7
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
7
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
8
8
|
import { ArrowLeftIcon, BoxIcon, CodeIcon, GlobeIcon, ServerIcon, TerminalIcon } from 'lucide-react';
|
|
9
9
|
import { headers } from 'next/headers';
|
|
10
10
|
import Link from 'next/link';
|
|
@@ -25,6 +25,7 @@ export const generateMetadata = generateAgentMetadata;
|
|
|
25
25
|
|
|
26
26
|
export default async function AgentIntegrationPage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
27
27
|
$sideEffect(headers());
|
|
28
|
+
|
|
28
29
|
const agentName = await getAgentName(params);
|
|
29
30
|
const isAdmin = await isUserAdmin();
|
|
30
31
|
|
|
@@ -170,7 +171,7 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
170
171
|
}
|
|
171
172
|
`);
|
|
172
173
|
|
|
173
|
-
const agentLinks = getAgentLinks(agentName);
|
|
174
|
+
const agentLinks = getAgentLinks(agentProfile.permanentId || agentName);
|
|
174
175
|
const chatLink = agentLinks.find((l) => l.title === 'Chat with Agent')!;
|
|
175
176
|
const websiteIntegrationLink = agentLinks.find((l) => l.title === 'Website Integration')!;
|
|
176
177
|
|
|
@@ -187,7 +188,13 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
187
188
|
{agentProfile.meta.image && (
|
|
188
189
|
// eslint-disable-next-line @next/next/no-img-element
|
|
189
190
|
<img
|
|
190
|
-
src={
|
|
191
|
+
src={
|
|
192
|
+
agentProfile.meta.image ||
|
|
193
|
+
generatePlaceholderAgentProfileImageUrl(
|
|
194
|
+
agentProfile.permanentId || agentName,
|
|
195
|
+
publicUrl,
|
|
196
|
+
)
|
|
197
|
+
}
|
|
191
198
|
alt={agentProfile.meta.fullname || agentName}
|
|
192
199
|
className="w-16 h-16 rounded-full object-cover border-2"
|
|
193
200
|
style={{ borderColor: primaryColor }}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use server';
|
|
2
2
|
|
|
3
3
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
4
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
4
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
5
5
|
import { ArrowLeftIcon, CodeIcon, HomeIcon, LinkIcon, ShareIcon } from 'lucide-react';
|
|
6
6
|
import { headers } from 'next/headers';
|
|
7
7
|
import Link from 'next/link';
|
|
@@ -9,15 +9,16 @@ import { notFound } from 'next/navigation';
|
|
|
9
9
|
import { Color } from '../../../../../../../src/utils/color/Color';
|
|
10
10
|
import { withAlpha } from '../../../../../../../src/utils/color/operators/withAlpha';
|
|
11
11
|
import { $sideEffect } from '../../../../../../../src/utils/organization/$sideEffect';
|
|
12
|
+
import { getAgentName, getAgentProfile } from '../_utils';
|
|
12
13
|
import { getAgentExternalLinks, getAgentLinks } from '../agentLinks';
|
|
13
14
|
import { CopyField } from '../CopyField';
|
|
14
|
-
import { getAgentName, getAgentProfile } from '../_utils';
|
|
15
15
|
import { generateAgentMetadata } from '../generateAgentMetadata';
|
|
16
16
|
|
|
17
17
|
export const generateMetadata = generateAgentMetadata;
|
|
18
18
|
|
|
19
19
|
export default async function AgentLinksPage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
20
20
|
$sideEffect(headers());
|
|
21
|
+
|
|
21
22
|
const agentName = await getAgentName(params);
|
|
22
23
|
|
|
23
24
|
let agentProfile;
|
|
@@ -56,7 +57,13 @@ export default async function AgentLinksPage({ params }: { params: Promise<{ age
|
|
|
56
57
|
{agentProfile.meta.image && (
|
|
57
58
|
// eslint-disable-next-line @next/next/no-img-element
|
|
58
59
|
<img
|
|
59
|
-
src={
|
|
60
|
+
src={
|
|
61
|
+
agentProfile.meta.image ||
|
|
62
|
+
generatePlaceholderAgentProfileImageUrl(
|
|
63
|
+
agentProfile.permanentId || agentName,
|
|
64
|
+
publicUrl,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
60
67
|
alt={agentProfile.meta.fullname || agentName}
|
|
61
68
|
className="w-16 h-16 rounded-full object-cover border-2"
|
|
62
69
|
style={{ borderColor: primaryColor }}
|
|
@@ -129,7 +136,7 @@ export default async function AgentLinksPage({ params }: { params: Promise<{ age
|
|
|
129
136
|
Agent Resources
|
|
130
137
|
</h2>
|
|
131
138
|
<div className="grid md:grid-cols-2 gap-4">
|
|
132
|
-
{getAgentLinks(agentName)
|
|
139
|
+
{getAgentLinks(agentProfile.permanentId || agentName)
|
|
133
140
|
.filter((link) =>
|
|
134
141
|
['Chat with Agent', 'History & Feedback', 'Integration'].includes(link.title),
|
|
135
142
|
)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
2
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
3
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
4
|
import { ImageResponse } from 'next/og';
|
|
4
5
|
import { assertsError } from '../../../../../../src/errors/assertsError';
|
|
@@ -24,6 +25,7 @@ export default async function Image({ params }: { params: Promise<{ agentName: s
|
|
|
24
25
|
const agentProfile = await getAgentProfile(agentName);
|
|
25
26
|
const agentColor = Color.from(agentProfile.meta.color || PROMPTBOOK_COLOR);
|
|
26
27
|
const backgroundColor = agentColor.then(grayscale(0.5));
|
|
28
|
+
const { publicUrl } = await $provideServer();
|
|
27
29
|
|
|
28
30
|
return new ImageResponse(
|
|
29
31
|
(
|
|
@@ -53,8 +55,15 @@ export default async function Image({ params }: { params: Promise<{ agentName: s
|
|
|
53
55
|
width: '80%',
|
|
54
56
|
backgroundColor: agentColor.toHex(),
|
|
55
57
|
borderRadius: '50%',
|
|
58
|
+
aspectRatio: '1 / 1',
|
|
56
59
|
}}
|
|
57
|
-
src={
|
|
60
|
+
src={
|
|
61
|
+
agentProfile.meta.image ||
|
|
62
|
+
generatePlaceholderAgentProfileImageUrl(
|
|
63
|
+
agentProfile.permanentId || agentName,
|
|
64
|
+
publicUrl,
|
|
65
|
+
)
|
|
66
|
+
}
|
|
58
67
|
alt="Agent Icon"
|
|
59
68
|
/>
|
|
60
69
|
</div>
|