@promptbook/cli 0.103.0 → 0.104.0-1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/apps/agents-server/src/app/agents/[agentName]/integration/WebsiteIntegrationTabs.tsx +26 -0
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +22 -5
- package/apps/agents-server/src/app/agents/[agentName]/website-integration/page.tsx +36 -17
- package/apps/agents-server/src/app/api/embed.js/route.ts +87 -67
- package/apps/agents-server/src/app/embed/layout.tsx +31 -0
- package/apps/agents-server/src/app/embed/page.tsx +22 -9
- package/esm/index.es.js +1 -1
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/book-components/PromptbookAgent/PromptbookAgentIntegration.d.ts +15 -0
- package/esm/typings/src/book-components/PromptbookAgent/PromptbookAgentSeamlessIntegration.d.ts +11 -2
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +1 -1
- package/umd/index.umd.js.map +1 -1
package/README.md
CHANGED
|
@@ -27,6 +27,10 @@ Turn your company's scattered knowledge into AI ready Books
|
|
|
27
27
|
|
|
28
28
|
|
|
29
29
|
|
|
30
|
+
<blockquote style="color: #ff8811">
|
|
31
|
+
<b>⚠ Warning:</b> This is a pre-release version of the library. It is not yet ready for production use. Please look at <a href="https://www.npmjs.com/package/@promptbook/core?activeTab=versions">latest stable release</a>.
|
|
32
|
+
</blockquote>
|
|
33
|
+
|
|
30
34
|
## 📦 Package `@promptbook/cli`
|
|
31
35
|
|
|
32
36
|
- Promptbooks are [divided into several](#-packages) packages, all are published from [single monorepo](https://github.com/webgptorg/promptbook).
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { CodePreview } from '../../../../../../_common/components/CodePreview/CodePreview';
|
|
4
|
+
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../../../../../_common/components/Tabs/Tabs';
|
|
5
|
+
|
|
6
|
+
type WebsiteIntegrationTabsProps = {
|
|
7
|
+
reactCode: string;
|
|
8
|
+
htmlCode: string;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export function WebsiteIntegrationTabs({ reactCode, htmlCode }: WebsiteIntegrationTabsProps) {
|
|
12
|
+
return (
|
|
13
|
+
<Tabs defaultValue="react" className="w-full">
|
|
14
|
+
<TabsList>
|
|
15
|
+
<TabsTrigger value="react">React</TabsTrigger>
|
|
16
|
+
<TabsTrigger value="html">HTML</TabsTrigger>
|
|
17
|
+
</TabsList>
|
|
18
|
+
<TabsContent value="react">
|
|
19
|
+
<CodePreview code={reactCode} language="typescript" />
|
|
20
|
+
</TabsContent>
|
|
21
|
+
<TabsContent value="html">
|
|
22
|
+
<CodePreview code={htmlCode} language="xml" />
|
|
23
|
+
</TabsContent>
|
|
24
|
+
</Tabs>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
@@ -14,11 +14,12 @@ import { Color } from '../../../../../../../src/utils/color/Color';
|
|
|
14
14
|
import { withAlpha } from '../../../../../../../src/utils/color/operators/withAlpha';
|
|
15
15
|
import { $sideEffect } from '../../../../../../../src/utils/organization/$sideEffect';
|
|
16
16
|
import { CodePreview } from '../../../../../../_common/components/CodePreview/CodePreview';
|
|
17
|
+
import { getAgentName, getAgentProfile } from '../_utils';
|
|
17
18
|
import { getAgentLinks } from '../agentLinks';
|
|
18
19
|
import { CopyField } from '../CopyField';
|
|
19
|
-
import { getAgentName, getAgentProfile } from '../_utils';
|
|
20
20
|
import { generateAgentMetadata } from '../generateAgentMetadata';
|
|
21
21
|
import { SdkCodeTabs } from './SdkCodeTabs';
|
|
22
|
+
import { WebsiteIntegrationTabs } from './WebsiteIntegrationTabs';
|
|
22
23
|
|
|
23
24
|
export const generateMetadata = generateAgentMetadata;
|
|
24
25
|
|
|
@@ -71,13 +72,13 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
71
72
|
|
|
72
73
|
// Website Integration Code
|
|
73
74
|
const { fullname, color, image, ...restMeta } = agentProfile.meta;
|
|
74
|
-
const
|
|
75
|
+
const websiteIntegrationReactCode = spaceTrim(
|
|
75
76
|
(block) => `
|
|
76
|
-
import {
|
|
77
|
+
import { PromptbookAgentIntegration } from '@promptbook/components';
|
|
77
78
|
|
|
78
79
|
export function YourComponent() {
|
|
79
80
|
return(
|
|
80
|
-
<
|
|
81
|
+
<PromptbookAgentIntegration
|
|
81
82
|
agentUrl="${baseUrl}"
|
|
82
83
|
meta={${block(JSON.stringify({ fullname, color, image, ...restMeta }, null, 4))}}
|
|
83
84
|
/>
|
|
@@ -86,6 +87,19 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
86
87
|
`,
|
|
87
88
|
);
|
|
88
89
|
|
|
90
|
+
// HTML Integration Code - use single quotes for meta attribute to allow JSON with double quotes inside
|
|
91
|
+
const metaJsonString = JSON.stringify({ fullname, color, image, ...restMeta }, null, 4);
|
|
92
|
+
const websiteIntegrationHtmlCode = spaceTrim(
|
|
93
|
+
(block) => `
|
|
94
|
+
<script src="${publicUrl.href}api/embed.js" async defer></script>
|
|
95
|
+
|
|
96
|
+
<promptbook-agent-integration
|
|
97
|
+
agent-url="${baseUrl}"
|
|
98
|
+
meta='${block(metaJsonString)}'
|
|
99
|
+
/>
|
|
100
|
+
`,
|
|
101
|
+
);
|
|
102
|
+
|
|
89
103
|
// OpenAI Compatible Curl
|
|
90
104
|
const curlCode = spaceTrim(`
|
|
91
105
|
curl ${agentApiBase}/api/openai/v1/chat/completions \\
|
|
@@ -214,7 +228,10 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
214
228
|
</p>
|
|
215
229
|
</div>
|
|
216
230
|
</div>
|
|
217
|
-
<
|
|
231
|
+
<WebsiteIntegrationTabs
|
|
232
|
+
reactCode={websiteIntegrationReactCode}
|
|
233
|
+
htmlCode={websiteIntegrationHtmlCode}
|
|
234
|
+
/>
|
|
218
235
|
</div>
|
|
219
236
|
|
|
220
237
|
{/* OpenAI API Compatible Endpoint */}
|
|
@@ -7,8 +7,9 @@ import { parseAgentSource } from '@promptbook-local/core';
|
|
|
7
7
|
import { headers } from 'next/headers';
|
|
8
8
|
import spaceTrim from 'spacetrim';
|
|
9
9
|
import { $sideEffect } from '../../../../../../../src/utils/organization/$sideEffect';
|
|
10
|
-
import {
|
|
10
|
+
import { just } from '../../../../../../../src/utils/organization/just';
|
|
11
11
|
import { generateAgentMetadata } from '../generateAgentMetadata';
|
|
12
|
+
import { WebsiteIntegrationTabs } from '../integration/WebsiteIntegrationTabs';
|
|
12
13
|
|
|
13
14
|
export const generateMetadata = generateAgentMetadata;
|
|
14
15
|
|
|
@@ -24,20 +25,31 @@ export default async function WebsiteIntegrationAgentPage({ params }: { params:
|
|
|
24
25
|
const { publicUrl } = await $provideServer();
|
|
25
26
|
const agentUrl = `${publicUrl.href}agents/${encodeURIComponent(agentName)}`;
|
|
26
27
|
|
|
27
|
-
const
|
|
28
|
+
const reactCode = spaceTrim(
|
|
28
29
|
(block) => `
|
|
29
|
-
|
|
30
|
-
import { PromptbookAgent } from '@promptbook/components';
|
|
30
|
+
import { PromptbookAgentIntegration } from '@promptbook/components';
|
|
31
31
|
|
|
32
32
|
export function YourComponent() {
|
|
33
33
|
return(
|
|
34
|
-
<
|
|
34
|
+
<PromptbookAgentIntegration
|
|
35
35
|
agentUrl="${agentUrl}"
|
|
36
36
|
meta={${block(JSON.stringify({ fullname, color, image, ...restMeta }, null, 4))}}
|
|
37
37
|
/>
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
|
-
|
|
40
|
+
`,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// HTML Integration Code - use single quotes for meta attribute to allow JSON with double quotes inside
|
|
44
|
+
const metaJsonString = JSON.stringify({ fullname, color, image, ...restMeta }, null, 4);
|
|
45
|
+
const htmlCode = spaceTrim(
|
|
46
|
+
(block) => `
|
|
47
|
+
<script src="${publicUrl.href}api/embed.js" async defer></script>
|
|
48
|
+
|
|
49
|
+
<promptbook-agent-integration
|
|
50
|
+
agent-url="${agentUrl}"
|
|
51
|
+
meta='${block(metaJsonString)}'
|
|
52
|
+
/>
|
|
41
53
|
`,
|
|
42
54
|
);
|
|
43
55
|
|
|
@@ -49,17 +61,24 @@ export default async function WebsiteIntegrationAgentPage({ params }: { params:
|
|
|
49
61
|
React application using the <code>{'<PromptbookAgent />'}</code> component.
|
|
50
62
|
</p>
|
|
51
63
|
|
|
52
|
-
<
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
64
|
+
<WebsiteIntegrationTabs reactCode={reactCode} htmlCode={htmlCode} />
|
|
65
|
+
{just(false) && (
|
|
66
|
+
<PromptbookAgentIntegration
|
|
67
|
+
// formfactor="profile"
|
|
68
|
+
agentUrl={agentUrl}
|
|
69
|
+
meta={meta}
|
|
70
|
+
style={
|
|
71
|
+
{
|
|
72
|
+
// width: '400px',
|
|
73
|
+
// height: '600px',
|
|
74
|
+
// outline: `2px solid red`
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
/>
|
|
78
|
+
)}
|
|
79
|
+
{htmlCode}
|
|
80
|
+
{just(true) && <div dangerouslySetInnerHTML={{ __html: htmlCode }} />}
|
|
81
|
+
{just(true) && <div dangerouslySetInnerHTML={{ __html: `<h1>Test</h1>` }} />}
|
|
63
82
|
</main>
|
|
64
83
|
);
|
|
65
84
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { spaceTrim } from '@promptbook-local/utils';
|
|
1
2
|
import { NextRequest, NextResponse } from 'next/server';
|
|
2
3
|
|
|
3
4
|
export async function GET(request: NextRequest) {
|
|
@@ -5,84 +6,103 @@ export async function GET(request: NextRequest) {
|
|
|
5
6
|
const host = request.nextUrl.host;
|
|
6
7
|
const baseUrl = `${protocol}//${host}`;
|
|
7
8
|
|
|
8
|
-
const script = `
|
|
9
|
-
(
|
|
10
|
-
if (customElements.get('promptbook-agent')) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
9
|
+
const script = spaceTrim(`
|
|
10
|
+
console.info('[🔌] Promptbook integration script from ${baseUrl}');
|
|
13
11
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
12
|
+
(function() {
|
|
13
|
+
if (customElements.get('promptbook-agent-integration')) {
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
19
16
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
17
|
+
class PromptbookAgentIntegrationElement extends HTMLElement {
|
|
18
|
+
constructor() {
|
|
19
|
+
super();
|
|
20
|
+
console.info('[🔌] Initializing <promptbook-agent-integration/>',this);
|
|
21
|
+
this.iframe = null;
|
|
22
|
+
}
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
24
|
+
static get observedAttributes() {
|
|
25
|
+
return ['agent-url', 'meta'];
|
|
26
|
+
}
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
connectedCallback() {
|
|
29
|
+
this.render();
|
|
30
|
+
window.addEventListener('message', this.handleMessage.bind(this));
|
|
31
|
+
}
|
|
32
32
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
37
|
-
}
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
window.removeEventListener('message', this.handleMessage.bind(this));
|
|
35
|
+
}
|
|
38
36
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
this.iframe.style.height = '650px';
|
|
44
|
-
this.iframe.style.maxHeight = '90vh';
|
|
45
|
-
this.iframe.style.maxWidth = '90vw';
|
|
46
|
-
this.iframe.style.boxShadow = '0 4px 12px rgba(0,0,0,0.15)';
|
|
47
|
-
this.iframe.style.borderRadius = '12px';
|
|
48
|
-
} else {
|
|
49
|
-
this.iframe.style.width = '60px';
|
|
50
|
-
this.iframe.style.height = '60px';
|
|
51
|
-
this.iframe.style.boxShadow = 'none';
|
|
52
|
-
this.iframe.style.borderRadius = '0';
|
|
37
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
38
|
+
if ((name === 'agent-url' || name === 'meta') && oldValue !== newValue) {
|
|
39
|
+
this.render();
|
|
40
|
+
}
|
|
53
41
|
}
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
42
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
43
|
+
handleMessage(event) {
|
|
44
|
+
if (event.data && event.data.type === 'PROMPTBOOK_AGENT_RESIZE') {
|
|
45
|
+
if (event.data.isOpen) {
|
|
46
|
+
// Match PromptbookAgentSeamlessIntegration.module.css dimensions
|
|
47
|
+
// Window is 380x600 + 20px padding on each side
|
|
48
|
+
this.iframe.style.width = '420px';
|
|
49
|
+
this.iframe.style.height = '640px';
|
|
50
|
+
this.iframe.style.maxHeight = 'calc(80vh + 40px)';
|
|
51
|
+
this.iframe.style.maxWidth = 'calc(100vw - 20px)';
|
|
52
|
+
} else {
|
|
53
|
+
// Closed state - button area with padding and shadow space
|
|
54
|
+
// Button is ~140px wide + 20px right margin + shadow space
|
|
55
|
+
this.iframe.style.width = '180px';
|
|
56
|
+
this.iframe.style.height = '100px';
|
|
57
|
+
this.iframe.style.maxHeight = 'none';
|
|
58
|
+
this.iframe.style.maxWidth = 'none';
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
60
62
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
this.iframe.style.border = 'none';
|
|
65
|
-
this.iframe.style.position = 'fixed';
|
|
66
|
-
this.iframe.style.bottom = '20px';
|
|
67
|
-
this.iframe.style.right = '20px';
|
|
68
|
-
this.iframe.style.width = '60px';
|
|
69
|
-
this.iframe.style.height = '60px';
|
|
70
|
-
this.iframe.style.zIndex = '2147483647'; // Max z-index
|
|
71
|
-
this.iframe.style.transition = 'width 0.3s ease, height 0.3s ease';
|
|
72
|
-
this.iframe.style.backgroundColor = 'transparent';
|
|
73
|
-
this.iframe.setAttribute('allow', 'microphone'); // Allow microphone if needed for voice
|
|
74
|
-
this.shadowRoot.appendChild(this.iframe);
|
|
75
|
-
}
|
|
63
|
+
render() {
|
|
64
|
+
const agentUrl = this.getAttribute('agent-url');
|
|
65
|
+
if (!agentUrl) return;
|
|
76
66
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
67
|
+
if (!this.iframe) {
|
|
68
|
+
this.attachShadow({ mode: 'open' });
|
|
69
|
+
this.iframe = document.createElement('iframe');
|
|
70
|
+
this.iframe.style.border = 'none';
|
|
71
|
+
this.iframe.style.position = 'fixed';
|
|
72
|
+
this.iframe.style.bottom = '0';
|
|
73
|
+
this.iframe.style.right = '0';
|
|
74
|
+
// Initial size for the closed button state (with padding and shadow space)
|
|
75
|
+
this.iframe.style.width = '180px';
|
|
76
|
+
this.iframe.style.height = '100px';
|
|
77
|
+
this.iframe.style.zIndex = '2147483647'; // Max z-index
|
|
78
|
+
this.iframe.style.transition = 'width 0.3s ease, height 0.3s ease';
|
|
79
|
+
this.iframe.style.backgroundColor = 'transparent';
|
|
80
|
+
this.iframe.setAttribute('allow', 'microphone'); // Allow microphone if needed for voice
|
|
81
|
+
this.shadowRoot.appendChild(this.iframe);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Construct embed URL pointing to the Next.js page we created
|
|
85
|
+
let embedUrl = '${baseUrl}/embed?agentUrl=' + encodeURIComponent(agentUrl);
|
|
86
|
+
|
|
87
|
+
// Add meta parameter if provided
|
|
88
|
+
const metaAttr = this.getAttribute('meta');
|
|
89
|
+
if (metaAttr) {
|
|
90
|
+
try {
|
|
91
|
+
// Validate that it's valid JSON
|
|
92
|
+
JSON.parse(metaAttr);
|
|
93
|
+
embedUrl += '&meta=' + encodeURIComponent(metaAttr);
|
|
94
|
+
} catch (e) {
|
|
95
|
+
console.error('[🔌] Invalid meta JSON:', e);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
this.iframe.src = embedUrl;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
82
102
|
|
|
83
|
-
|
|
84
|
-
})();
|
|
85
|
-
|
|
103
|
+
customElements.define('promptbook-agent-integration', PromptbookAgentIntegrationElement);
|
|
104
|
+
})();
|
|
105
|
+
`);
|
|
86
106
|
|
|
87
107
|
return new NextResponse(script, {
|
|
88
108
|
headers: {
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Metadata } from 'next';
|
|
2
|
+
|
|
3
|
+
export const metadata: Metadata = {
|
|
4
|
+
title: 'Promptbook Agent Embed',
|
|
5
|
+
description: 'Embedded agent chat widget',
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Minimal layout for the embed page - no header, footer, or other UI elements
|
|
10
|
+
* This layout is completely transparent and only renders the chat widget
|
|
11
|
+
*/
|
|
12
|
+
export default function EmbedLayout({
|
|
13
|
+
children,
|
|
14
|
+
}: Readonly<{
|
|
15
|
+
children: React.ReactNode;
|
|
16
|
+
}>) {
|
|
17
|
+
return (
|
|
18
|
+
<html lang="en">
|
|
19
|
+
<body
|
|
20
|
+
style={{
|
|
21
|
+
margin: 0,
|
|
22
|
+
padding: 0,
|
|
23
|
+
background: 'transparent',
|
|
24
|
+
overflow: 'hidden',
|
|
25
|
+
}}
|
|
26
|
+
>
|
|
27
|
+
{children}
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
30
|
+
);
|
|
31
|
+
}
|
|
@@ -2,23 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
import { PromptbookAgentIntegration } from '@promptbook-local/components';
|
|
4
4
|
import { useSearchParams } from 'next/navigation';
|
|
5
|
+
import { useMemo } from 'react';
|
|
5
6
|
|
|
6
7
|
export default function EmbedPage() {
|
|
7
8
|
const searchParams = useSearchParams();
|
|
8
9
|
const agentUrl = searchParams.get('agentUrl');
|
|
10
|
+
const metaParam = searchParams.get('meta');
|
|
11
|
+
|
|
12
|
+
const meta = useMemo(() => {
|
|
13
|
+
if (!metaParam) {
|
|
14
|
+
return undefined;
|
|
15
|
+
}
|
|
16
|
+
try {
|
|
17
|
+
return JSON.parse(metaParam);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
console.error('[🔌] Failed to parse meta parameter:', e);
|
|
20
|
+
return undefined;
|
|
21
|
+
}
|
|
22
|
+
}, [metaParam]);
|
|
9
23
|
|
|
10
24
|
if (!agentUrl) {
|
|
11
|
-
return <div
|
|
25
|
+
return <div style={{ color: 'red' }}>Missing agentUrl parameter</div>;
|
|
12
26
|
}
|
|
13
27
|
|
|
14
28
|
return (
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
</div>
|
|
29
|
+
<PromptbookAgentIntegration
|
|
30
|
+
agentUrl={agentUrl}
|
|
31
|
+
meta={meta}
|
|
32
|
+
onOpenChange={(isOpen) => {
|
|
33
|
+
window.parent.postMessage({ type: 'PROMPTBOOK_AGENT_RESIZE', isOpen }, '*');
|
|
34
|
+
}}
|
|
35
|
+
/>
|
|
23
36
|
);
|
|
24
37
|
}
|
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.
|
|
50
|
+
const PROMPTBOOK_ENGINE_VERSION = '0.104.0-1';
|
|
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
|