@promptbook/cli 0.104.0-7 → 0.104.0-9
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/src/app/AddAgentButton.tsx +45 -19
- package/apps/agents-server/src/app/actions.ts +5 -0
- package/apps/agents-server/src/app/admin/browser-test/BrowserTestClient.tsx +108 -0
- package/apps/agents-server/src/app/admin/browser-test/page.tsx +13 -0
- package/apps/agents-server/src/app/agents/[agentName]/AgentProfileWrapper.tsx +49 -10
- package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +2 -4
- package/apps/agents-server/src/app/agents/[agentName]/api/book/route.ts +4 -2
- package/apps/agents-server/src/app/agents/[agentName]/code/page.tsx +4 -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/route.ts +12 -5
- package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +10 -2
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +5 -5
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +5 -5
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +8 -2
- package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +8 -2
- package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +4 -3
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +3 -5
- package/apps/agents-server/src/app/agents/[agentName]/system-message/page.tsx +15 -4
- package/apps/agents-server/src/app/api/agents/[agentName]/clone/route.ts +3 -2
- package/apps/agents-server/src/app/api/agents/[agentName]/restore/route.ts +2 -1
- package/apps/agents-server/src/app/api/agents/[agentName]/route.ts +2 -1
- 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/humans.txt/route.ts +1 -1
- package/apps/agents-server/src/app/page.tsx +4 -2
- package/apps/agents-server/src/app/recycle-bin/page.tsx +3 -1
- 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 +4 -5
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +25 -20
- package/apps/agents-server/src/components/AgentProfile/AgentProfileImage.tsx +79 -0
- package/apps/agents-server/src/components/Header/Header.tsx +4 -0
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +46 -10
- package/apps/agents-server/src/components/Homepage/AgentsList.tsx +32 -14
- package/apps/agents-server/src/components/Homepage/DeletedAgentsList.tsx +22 -6
- 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/NewAgentDialog/NewAgentDialog.tsx +88 -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/database/migrations/2025-12-0820-agent-history-permanent-id.sql +29 -0
- package/apps/agents-server/src/database/schema.ts +6 -3
- package/apps/agents-server/src/tools/$provideBrowserForServer.ts +29 -0
- package/apps/agents-server/src/tools/$provideCdnForServer.ts +1 -1
- package/esm/index.es.js +7 -2
- package/esm/index.es.js.map +1 -1
- 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 +2 -2
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentCollectionInSupabase.d.ts +10 -6
- package/esm/typings/src/collection/agent-collection/constructors/agent-collection-in-supabase/AgentsDatabaseSchema.d.ts +6 -3
- package/esm/typings/src/utils/color/utils/colorToDataUrl.d.ts +2 -1
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +7 -2
- package/umd/index.umd.js.map +1 -1
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
// Client Component for rendering and deleting agents
|
|
2
2
|
'use client';
|
|
3
3
|
|
|
4
|
-
import React, { useState } from 'react';
|
|
5
|
-
import { useRouter } from 'next/navigation';
|
|
6
4
|
import { TrashIcon } from 'lucide-react';
|
|
7
5
|
import Link from 'next/link';
|
|
6
|
+
import { useRouter } from 'next/navigation';
|
|
7
|
+
import { useState } from 'react';
|
|
8
8
|
import { AddAgentButton } from '../../app/AddAgentButton';
|
|
9
9
|
import { AgentCard } from './AgentCard';
|
|
10
10
|
import { Section } from './Section';
|
|
@@ -16,16 +16,29 @@ type AgentWithVisibility = AgentBasicInformation & {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
type AgentsListProps = {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
/**
|
|
20
|
+
* @@@
|
|
21
|
+
*/
|
|
22
|
+
readonly agents: AgentWithVisibility[];
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* @@@
|
|
26
|
+
*/
|
|
27
|
+
readonly isAdmin: boolean;
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Base URL of the agents server
|
|
31
|
+
*/
|
|
32
|
+
readonly publicUrl: URL;
|
|
21
33
|
};
|
|
22
34
|
|
|
23
|
-
export function AgentsList(
|
|
35
|
+
export function AgentsList(props: AgentsListProps) {
|
|
36
|
+
const { agents: initialAgents, isAdmin, publicUrl } = props;
|
|
24
37
|
const router = useRouter();
|
|
25
38
|
const [agents, setAgents] = useState(Array.from(initialAgents));
|
|
26
39
|
|
|
27
40
|
const handleDelete = async (agentIdentifier: string) => {
|
|
28
|
-
const agent = agents.find(a => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
41
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
29
42
|
if (!agent) return;
|
|
30
43
|
if (!window.confirm(`Delete agent "${agent.agentName}"? It will be moved to Recycle Bin.`)) return;
|
|
31
44
|
|
|
@@ -45,12 +58,14 @@ export function AgentsList({ agents: initialAgents, isAdmin }: AgentsListProps)
|
|
|
45
58
|
};
|
|
46
59
|
|
|
47
60
|
const handleClone = async (agentIdentifier: string) => {
|
|
48
|
-
const agent = agents.find(a => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
61
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
49
62
|
if (!agent) return;
|
|
50
63
|
if (!window.confirm(`Clone agent "${agent.agentName}"?`)) return;
|
|
51
64
|
|
|
52
65
|
try {
|
|
53
|
-
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/clone`, {
|
|
66
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/clone`, {
|
|
67
|
+
method: 'POST',
|
|
68
|
+
});
|
|
54
69
|
if (response.ok) {
|
|
55
70
|
const newAgent = await response.json();
|
|
56
71
|
setAgents([...agents, newAgent]);
|
|
@@ -64,7 +79,7 @@ export function AgentsList({ agents: initialAgents, isAdmin }: AgentsListProps)
|
|
|
64
79
|
};
|
|
65
80
|
|
|
66
81
|
const handleToggleVisibility = async (agentIdentifier: string) => {
|
|
67
|
-
const agent = agents.find(a => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
82
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
68
83
|
if (!agent) return;
|
|
69
84
|
|
|
70
85
|
const newVisibility = agent.visibility === 'PUBLIC' ? 'PRIVATE' : 'PUBLIC';
|
|
@@ -78,11 +93,13 @@ export function AgentsList({ agents: initialAgents, isAdmin }: AgentsListProps)
|
|
|
78
93
|
|
|
79
94
|
if (response.ok) {
|
|
80
95
|
// Update the local state
|
|
81
|
-
setAgents(
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
96
|
+
setAgents(
|
|
97
|
+
agents.map((a) =>
|
|
98
|
+
a.permanentId === agent.permanentId || a.agentName === agent.agentName
|
|
99
|
+
? { ...a, visibility: newVisibility }
|
|
100
|
+
: a,
|
|
101
|
+
),
|
|
102
|
+
);
|
|
86
103
|
router.refresh(); // Refresh server data to ensure consistency
|
|
87
104
|
} else {
|
|
88
105
|
alert('Failed to update agent visibility');
|
|
@@ -95,6 +112,7 @@ export function AgentsList({ agents: initialAgents, isAdmin }: AgentsListProps)
|
|
|
95
112
|
<AgentCard
|
|
96
113
|
key={agent.permanentId || agent.agentName}
|
|
97
114
|
agent={agent}
|
|
115
|
+
publicUrl={publicUrl}
|
|
98
116
|
href={`/agents/${encodeURIComponent(agent.permanentId || agent.agentName)}`}
|
|
99
117
|
isAdmin={isAdmin}
|
|
100
118
|
onDelete={handleDelete}
|
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
// Client Component for rendering deleted agents
|
|
2
2
|
'use client';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { useState } from 'react';
|
|
5
5
|
import { AgentCard } from './AgentCard';
|
|
6
6
|
|
|
7
7
|
import { AgentBasicInformation } from '../../../../../src/book-2.0/agent-source/AgentBasicInformation';
|
|
8
8
|
|
|
9
9
|
type DeletedAgentsListProps = {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
/**
|
|
11
|
+
* @@@
|
|
12
|
+
*/
|
|
13
|
+
readonly agents: readonly AgentBasicInformation[];
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @@@
|
|
17
|
+
*/
|
|
18
|
+
readonly isAdmin: boolean;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Base URL of the agents server
|
|
22
|
+
*/
|
|
23
|
+
readonly publicUrl: URL;
|
|
12
24
|
};
|
|
13
25
|
|
|
14
|
-
export function DeletedAgentsList(
|
|
26
|
+
export function DeletedAgentsList(props: DeletedAgentsListProps) {
|
|
27
|
+
const { agents: initialAgents, isAdmin, publicUrl } = props;
|
|
15
28
|
const [agents, setAgents] = useState(Array.from(initialAgents));
|
|
16
29
|
|
|
17
30
|
const handleRestore = async (agentIdentifier: string) => {
|
|
18
|
-
const agent = agents.find(a => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
31
|
+
const agent = agents.find((a) => a.permanentId === agentIdentifier || a.agentName === agentIdentifier);
|
|
19
32
|
if (!agent) return;
|
|
20
33
|
if (!window.confirm(`Restore agent "${agent.agentName}"?`)) return;
|
|
21
34
|
|
|
22
35
|
try {
|
|
23
|
-
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/restore`, {
|
|
36
|
+
const response = await fetch(`/api/agents/${encodeURIComponent(agentIdentifier)}/restore`, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
});
|
|
24
39
|
if (response.ok) {
|
|
25
40
|
// Update local state immediately
|
|
26
41
|
setAgents(agents.filter((a) => a.permanentId !== agent.permanentId && a.agentName !== agent.agentName));
|
|
@@ -40,6 +55,7 @@ export function DeletedAgentsList({ agents: initialAgents, isAdmin }: DeletedAge
|
|
|
40
55
|
<AgentCard
|
|
41
56
|
key={agent.permanentId || agent.agentName}
|
|
42
57
|
agent={agent}
|
|
58
|
+
publicUrl={publicUrl}
|
|
43
59
|
href={`/agents/${encodeURIComponent(agent.permanentId || agent.agentName)}`}
|
|
44
60
|
isAdmin={isAdmin}
|
|
45
61
|
onRestore={handleRestore}
|
|
@@ -3,16 +3,25 @@ import { AgentCard } from './AgentCard';
|
|
|
3
3
|
import { Section } from './Section';
|
|
4
4
|
|
|
5
5
|
type ExternalAgentsSectionProps = {
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* @@@
|
|
8
|
+
*/
|
|
9
|
+
readonly agentsByServer: AgentsByServer[];
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Base URL of the agents server
|
|
13
|
+
*/
|
|
14
|
+
readonly publicUrl: URL;
|
|
7
15
|
};
|
|
8
16
|
|
|
9
|
-
export function ExternalAgentsSection(
|
|
17
|
+
export function ExternalAgentsSection(props: ExternalAgentsSectionProps) {
|
|
18
|
+
const { agentsByServer, publicUrl } = props;
|
|
10
19
|
return (
|
|
11
20
|
<>
|
|
12
21
|
{agentsByServer.map(({ serverUrl, agents }) => (
|
|
13
22
|
<Section key={serverUrl} title={`Agents from ${new URL(serverUrl).hostname} (${agents.length})`}>
|
|
14
23
|
{agents.map((agent) => (
|
|
15
|
-
<AgentCard key={agent.url} agent={agent} href={agent.url} />
|
|
24
|
+
<AgentCard key={agent.url} agent={agent} href={agent.url} publicUrl={publicUrl} />
|
|
16
25
|
))}
|
|
17
26
|
</Section>
|
|
18
27
|
))}
|
|
@@ -15,7 +15,15 @@ type ServerState = {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
type ExternalAgentsSectionClientProps = {
|
|
19
|
+
/**
|
|
20
|
+
* Base URL of the agents server
|
|
21
|
+
*/
|
|
22
|
+
readonly publicUrl: URL;
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export function ExternalAgentsSectionClient(props: ExternalAgentsSectionClientProps) {
|
|
26
|
+
const { publicUrl } = props;
|
|
19
27
|
const [servers, setServers] = useState<Record<string, ServerState>>({});
|
|
20
28
|
const [initialLoading, setInitialLoading] = useState(true);
|
|
21
29
|
|
|
@@ -26,24 +34,23 @@ export function ExternalAgentsSectionClient() {
|
|
|
26
34
|
try {
|
|
27
35
|
const response = await fetch('/api/federated-agents');
|
|
28
36
|
if (!response.ok) throw new Error('Failed to fetch federated servers');
|
|
29
|
-
|
|
37
|
+
|
|
30
38
|
const data: FederatedServersResponse = await response.json();
|
|
31
|
-
|
|
39
|
+
|
|
32
40
|
if (isCancelled) return;
|
|
33
41
|
|
|
34
42
|
const initialServerState: Record<string, ServerState> = {};
|
|
35
|
-
data.federatedServers.forEach(serverUrl => {
|
|
43
|
+
data.federatedServers.forEach((serverUrl) => {
|
|
36
44
|
initialServerState[serverUrl] = { status: 'loading', agents: [] };
|
|
37
45
|
});
|
|
38
|
-
|
|
46
|
+
|
|
39
47
|
setServers(initialServerState);
|
|
40
48
|
setInitialLoading(false);
|
|
41
49
|
|
|
42
50
|
// Fetch agents for each server independently
|
|
43
|
-
data.federatedServers.forEach(serverUrl => {
|
|
51
|
+
data.federatedServers.forEach((serverUrl) => {
|
|
44
52
|
fetchAgentsForServer(serverUrl);
|
|
45
53
|
});
|
|
46
|
-
|
|
47
54
|
} catch (error) {
|
|
48
55
|
console.error('Failed to load federated servers list', error);
|
|
49
56
|
if (!isCancelled) setInitialLoading(false);
|
|
@@ -80,7 +87,9 @@ export function ExternalAgentsSectionClient() {
|
|
|
80
87
|
const response = await fetch(proxyUrl);
|
|
81
88
|
|
|
82
89
|
if (!response.ok) {
|
|
83
|
-
throw new Error(
|
|
90
|
+
throw new Error(
|
|
91
|
+
`Failed to fetch agents from ${serverUrl} via proxy (Status: ${response.status})`,
|
|
92
|
+
);
|
|
84
93
|
}
|
|
85
94
|
|
|
86
95
|
const data = await response.json();
|
|
@@ -134,7 +143,7 @@ export function ExternalAgentsSectionClient() {
|
|
|
134
143
|
|
|
135
144
|
return (
|
|
136
145
|
<>
|
|
137
|
-
{serverUrls.map(serverUrl => {
|
|
146
|
+
{serverUrls.map((serverUrl) => {
|
|
138
147
|
const state = servers[serverUrl];
|
|
139
148
|
const hostname = (() => {
|
|
140
149
|
try {
|
|
@@ -169,7 +178,7 @@ export function ExternalAgentsSectionClient() {
|
|
|
169
178
|
return (
|
|
170
179
|
<Section key={serverUrl} title={`Agents from ${hostname} (${state.agents.length})`}>
|
|
171
180
|
{state.agents.map((agent) => (
|
|
172
|
-
<AgentCard key={agent.url} agent={agent} href={agent.url} />
|
|
181
|
+
<AgentCard key={agent.url} agent={agent} href={agent.url} publicUrl={publicUrl} />
|
|
173
182
|
))}
|
|
174
183
|
</Section>
|
|
175
184
|
);
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { string_book } from '@promptbook-local/types';
|
|
4
|
+
import { X } from 'lucide-react';
|
|
5
|
+
import { useEffect, useState } from 'react';
|
|
6
|
+
import { BookEditor } from '../../../../../src/book-components/BookEditor/BookEditor';
|
|
7
|
+
import { Portal } from '../Portal/Portal';
|
|
8
|
+
|
|
9
|
+
type NewAgentDialogProps = {
|
|
10
|
+
isOpen: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
initialAgentSource: string_book;
|
|
13
|
+
onCreate: (agentSource: string_book) => Promise<void>;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export function NewAgentDialog(props: NewAgentDialogProps) {
|
|
17
|
+
const { isOpen, onClose, initialAgentSource, onCreate } = props;
|
|
18
|
+
const [agentSource, setAgentSource] = useState(initialAgentSource);
|
|
19
|
+
const [isCreating, setIsCreating] = useState(false);
|
|
20
|
+
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
setAgentSource(initialAgentSource);
|
|
23
|
+
}, [initialAgentSource]);
|
|
24
|
+
|
|
25
|
+
if (!isOpen) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const handleCreate = async () => {
|
|
30
|
+
setIsCreating(true);
|
|
31
|
+
try {
|
|
32
|
+
await onCreate(agentSource);
|
|
33
|
+
} finally {
|
|
34
|
+
setIsCreating(false);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<Portal>
|
|
40
|
+
<div className="fixed inset-0 z-[9999] flex items-center justify-center bg-black/50 backdrop-blur-sm animate-in fade-in duration-200">
|
|
41
|
+
<div className="relative w-full max-w-4xl h-[80vh] bg-white rounded-lg shadow-lg border border-gray-200 flex flex-col animate-in zoom-in-95 duration-200">
|
|
42
|
+
<div className="flex items-center justify-between p-4 border-b border-gray-200">
|
|
43
|
+
<h2 className="text-xl font-semibold text-gray-900">Create New Agent</h2>
|
|
44
|
+
<button
|
|
45
|
+
onClick={onClose}
|
|
46
|
+
className="text-gray-400 hover:text-gray-500 transition-colors"
|
|
47
|
+
>
|
|
48
|
+
<X className="w-5 h-5" />
|
|
49
|
+
<span className="sr-only">Close</span>
|
|
50
|
+
</button>
|
|
51
|
+
</div>
|
|
52
|
+
|
|
53
|
+
<div className="flex-1 overflow-hidden p-4">
|
|
54
|
+
<BookEditor
|
|
55
|
+
agentSource={agentSource}
|
|
56
|
+
onChange={(source) => setAgentSource(source)}
|
|
57
|
+
height="100%"
|
|
58
|
+
isVerbose={false}
|
|
59
|
+
/>
|
|
60
|
+
</div>
|
|
61
|
+
|
|
62
|
+
<div className="flex items-center justify-end gap-3 p-4 border-t border-gray-200 bg-gray-50 rounded-b-lg">
|
|
63
|
+
<button
|
|
64
|
+
onClick={onClose}
|
|
65
|
+
className="px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-100 rounded-md transition-colors"
|
|
66
|
+
>
|
|
67
|
+
Cancel
|
|
68
|
+
</button>
|
|
69
|
+
<button
|
|
70
|
+
onClick={handleCreate}
|
|
71
|
+
disabled={isCreating}
|
|
72
|
+
className="px-4 py-2 text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed flex items-center gap-2"
|
|
73
|
+
>
|
|
74
|
+
{isCreating ? (
|
|
75
|
+
<>
|
|
76
|
+
<span className="inline-block h-4 w-4 animate-spin rounded-full border-2 border-white border-t-transparent" />
|
|
77
|
+
Creating...
|
|
78
|
+
</>
|
|
79
|
+
) : (
|
|
80
|
+
'Create Agent'
|
|
81
|
+
)}
|
|
82
|
+
</button>
|
|
83
|
+
</div>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
</Portal>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {
|
|
2
|
+
NEXT_PUBLIC_SITE_URL,
|
|
2
3
|
NEXT_PUBLIC_VERCEL_BRANCH_URL,
|
|
3
4
|
NEXT_PUBLIC_VERCEL_ENV,
|
|
4
5
|
NEXT_PUBLIC_VERCEL_GIT_COMMIT_AUTHOR_LOGIN,
|
|
@@ -24,6 +25,7 @@ import { TechInfoCard } from '../Homepage/TechInfoCard';
|
|
|
24
25
|
export default function VercelDeploymentCard() {
|
|
25
26
|
return (
|
|
26
27
|
<TechInfoCard title="Vercel Deployment">
|
|
28
|
+
<p className="text-gray-600">NEXT_PUBLIC_SITE_URL: {NEXT_PUBLIC_SITE_URL?.href || 'undefined'}</p>
|
|
27
29
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_ENV: {NEXT_PUBLIC_VERCEL_ENV}</p>
|
|
28
30
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_TARGET_ENV: {NEXT_PUBLIC_VERCEL_TARGET_ENV}</p>
|
|
29
31
|
<p className="text-gray-600">NEXT_PUBLIC_VERCEL_URL: {NEXT_PUBLIC_VERCEL_URL}</p>
|
|
@@ -1,26 +1,28 @@
|
|
|
1
1
|
// Utility to generate content for robots.txt, security.txt, and humans.txt [DRY]
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { $provideServer } from '@/src/tools/$provideServer';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
|
|
8
|
-
export function generateRobotsTxt(): string {
|
|
9
|
-
return ['User-agent: *', `Sitemap: ${baseUrl}sitemap.xml`, ''].join('\n');
|
|
5
|
+
export async function generateRobotsTxt(): Promise<string> {
|
|
6
|
+
const { publicUrl } = await $provideServer();
|
|
7
|
+
return ['User-agent: *', `Sitemap: ${publicUrl.href}sitemap.xml`, ''].join('\n');
|
|
10
8
|
}
|
|
11
9
|
|
|
12
|
-
export function generateSecurityTxt(): string {
|
|
10
|
+
export async function generateSecurityTxt(): Promise<string> {
|
|
11
|
+
const { publicUrl } = await $provideServer();
|
|
13
12
|
// See https://securitytxt.org/ for more fields
|
|
14
13
|
return [
|
|
15
14
|
`Contact: mailto:security@ptbk.io`,
|
|
16
15
|
`Expires: ${new Date(Date.now() + 365 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]}`,
|
|
17
|
-
`Canonical: ${
|
|
16
|
+
`Canonical: ${publicUrl.href}security.txt`,
|
|
18
17
|
'',
|
|
19
18
|
].join('\n');
|
|
20
19
|
}
|
|
21
20
|
|
|
22
|
-
export function generateHumansTxt(): string {
|
|
23
|
-
|
|
21
|
+
export async function generateHumansTxt(): Promise<string> {
|
|
22
|
+
const { publicUrl } = await $provideServer();
|
|
23
|
+
return ['/* TEAM */', 'Developer: Promptbook Team', `Site: https://ptbk.io`, `Instance: ${publicUrl.href}`].join(
|
|
24
|
+
'\n',
|
|
25
|
+
);
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
/**
|
package/apps/agents-server/src/database/migrations/2025-12-0820-agent-history-permanent-id.sql
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
-- Backfill permanentId in Agent table if missing
|
|
2
|
+
UPDATE "prefix_Agent"
|
|
3
|
+
SET "permanentId" = gen_random_uuid()::text
|
|
4
|
+
WHERE "permanentId" IS NULL;
|
|
5
|
+
|
|
6
|
+
-- Add permanentId column to AgentHistory
|
|
7
|
+
ALTER TABLE "prefix_AgentHistory" ADD COLUMN "permanentId" TEXT;
|
|
8
|
+
|
|
9
|
+
-- Backfill permanentId from Agent table
|
|
10
|
+
UPDATE "prefix_AgentHistory" ah
|
|
11
|
+
SET "permanentId" = a."permanentId"
|
|
12
|
+
FROM "prefix_Agent" a
|
|
13
|
+
WHERE ah."agentName" = a."agentName";
|
|
14
|
+
|
|
15
|
+
-- Make permanentId NOT NULL
|
|
16
|
+
ALTER TABLE "prefix_AgentHistory" ALTER COLUMN "permanentId" SET NOT NULL;
|
|
17
|
+
|
|
18
|
+
-- Drop old foreign key on agentName
|
|
19
|
+
ALTER TABLE "prefix_AgentHistory" DROP CONSTRAINT "prefix_AgentHistory_agentName_fkey";
|
|
20
|
+
|
|
21
|
+
-- Add new foreign key on permanentId referencing Agent(permanentId)
|
|
22
|
+
ALTER TABLE "prefix_AgentHistory"
|
|
23
|
+
ADD CONSTRAINT "prefix_AgentHistory_permanentId_fkey"
|
|
24
|
+
FOREIGN KEY ("permanentId")
|
|
25
|
+
REFERENCES "prefix_Agent"("permanentId")
|
|
26
|
+
ON DELETE CASCADE;
|
|
27
|
+
|
|
28
|
+
-- Add index for permanentId
|
|
29
|
+
CREATE INDEX "prefix_AgentHistory_permanentId_idx" ON "prefix_AgentHistory" ("permanentId");
|
|
@@ -97,6 +97,7 @@ export type AgentsServerDatabase = {
|
|
|
97
97
|
id: number;
|
|
98
98
|
createdAt: string;
|
|
99
99
|
agentName: string;
|
|
100
|
+
permanentId: string;
|
|
100
101
|
agentHash: string;
|
|
101
102
|
previousAgentHash: string | null;
|
|
102
103
|
agentSource: string;
|
|
@@ -106,6 +107,7 @@ export type AgentsServerDatabase = {
|
|
|
106
107
|
id?: number;
|
|
107
108
|
createdAt: string;
|
|
108
109
|
agentName: string;
|
|
110
|
+
permanentId: string;
|
|
109
111
|
agentHash: string;
|
|
110
112
|
previousAgentHash?: string | null;
|
|
111
113
|
agentSource: string;
|
|
@@ -115,6 +117,7 @@ export type AgentsServerDatabase = {
|
|
|
115
117
|
id?: number;
|
|
116
118
|
createdAt?: string;
|
|
117
119
|
agentName?: string;
|
|
120
|
+
permanentId?: string;
|
|
118
121
|
agentHash?: string;
|
|
119
122
|
previousAgentHash?: string | null;
|
|
120
123
|
agentSource?: string;
|
|
@@ -122,10 +125,10 @@ export type AgentsServerDatabase = {
|
|
|
122
125
|
};
|
|
123
126
|
Relationships: [
|
|
124
127
|
{
|
|
125
|
-
foreignKeyName: '
|
|
126
|
-
columns: ['
|
|
128
|
+
foreignKeyName: 'AgentHistory_permanentId_fkey';
|
|
129
|
+
columns: ['permanentId'];
|
|
127
130
|
referencedRelation: 'Agent';
|
|
128
|
-
referencedColumns: ['
|
|
131
|
+
referencedColumns: ['permanentId'];
|
|
129
132
|
},
|
|
130
133
|
];
|
|
131
134
|
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { locateChrome } from 'locate-app';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { BrowserContext, chromium } from 'playwright';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Cache of browser instance
|
|
7
|
+
*
|
|
8
|
+
* @private internal cache for `$provideBrowserForServer`
|
|
9
|
+
*/
|
|
10
|
+
let browserInstance: BrowserContext | null = null;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @@@
|
|
14
|
+
*/
|
|
15
|
+
export async function $provideBrowserForServer(): Promise<BrowserContext> {
|
|
16
|
+
if (browserInstance === null /* || !browserInstance.isConnected() */) {
|
|
17
|
+
console.log('Launching new browser instance...');
|
|
18
|
+
browserInstance = await chromium.launchPersistentContext(
|
|
19
|
+
join(process.cwd(), '.promptbook', 'puppeteer', 'user-data'),
|
|
20
|
+
{
|
|
21
|
+
executablePath: await locateChrome(),
|
|
22
|
+
headless: false,
|
|
23
|
+
// defaultViewport: null,
|
|
24
|
+
// downloadsPath
|
|
25
|
+
},
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
return browserInstance;
|
|
29
|
+
}
|
package/esm/index.es.js
CHANGED
|
@@ -47,7 +47,7 @@ const BOOK_LANGUAGE_VERSION = '2.0.0';
|
|
|
47
47
|
* @generated
|
|
48
48
|
* @see https://github.com/webgptorg/promptbook
|
|
49
49
|
*/
|
|
50
|
-
const PROMPTBOOK_ENGINE_VERSION = '0.104.0-
|
|
50
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.104.0-9';
|
|
51
51
|
/**
|
|
52
52
|
* TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
|
|
53
53
|
* Note: [💞] Ignore a discrepancy between file name and entity name
|
|
@@ -26421,7 +26421,12 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
26421
26421
|
};
|
|
26422
26422
|
}
|
|
26423
26423
|
// Apply each commitment in order using reduce-like pattern
|
|
26424
|
-
for (
|
|
26424
|
+
for (let i = 0; i < filteredCommitments.length; i++) {
|
|
26425
|
+
const commitment = filteredCommitments[i];
|
|
26426
|
+
// CLOSED commitment should work only if its the last commitment in the book
|
|
26427
|
+
if (commitment.type === 'CLOSED' && i !== filteredCommitments.length - 1) {
|
|
26428
|
+
continue;
|
|
26429
|
+
}
|
|
26425
26430
|
const definition = getCommitmentDefinition(commitment.type);
|
|
26426
26431
|
if (definition) {
|
|
26427
26432
|
try {
|