Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2f814ae
build(deps): bump @radix-ui/react-icons from 1.3.0 to 1.3.2
dependabot[bot] Nov 14, 2024
82e34e5
build(deps): bump @vitejs/plugin-react from 4.3.2 to 4.3.4
dependabot[bot] Nov 27, 2024
b2a09f2
feat: add PDF export functionality for chat transcripts and update UI…
marcolivierbouch Jul 22, 2025
a881e7f
feat: add changeset
marcolivierbouch Jul 23, 2025
0dd70df
feat: remove lock
marcolivierbouch Jul 23, 2025
ca63eac
feat: add lock
marcolivierbouch Jul 23, 2025
1fcce45
feat: remove lock
marcolivierbouch Jul 23, 2025
1e3b8f3
feat: update lock
marcolivierbouch Jul 23, 2025
4a4a9ec
feat update pnpm version
marcolivierbouch Jul 23, 2025
eca1a10
fix prettier
marcolivierbouch Jul 23, 2025
e706f40
Merge pull request #170 from OpenAssistantGPT/dependabot/npm_and_yarn…
marcolivierbouch Jul 23, 2025
b16164c
Merge pull request #173 from OpenAssistantGPT/dependabot/npm_and_yarn…
marcolivierbouch Jul 23, 2025
5a6b850
Merge branch 'main' of github.com:OpenAssistantGPT/OpenAssistantGPT-S…
marcolivierbouch Jul 23, 2025
03171c5
update
marcolivierbouch Jul 23, 2025
cc1e30b
run prettier
marcolivierbouch Jul 23, 2025
0a929f9
Merge pull request #223 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
09f3de8
feat: udpate
marcolivierbouch Jul 23, 2025
099d8ca
feat: update
marcolivierbouch Jul 23, 2025
f225a4b
Merge pull request #224 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
bbed25b
feat: remove changeset
marcolivierbouch Jul 23, 2025
7eeedac
Merge pull request #225 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
cfcd99b
feat: upate
marcolivierbouch Jul 23, 2025
ceb9e8e
Merge pull request #226 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
27d5b1c
feat: update
marcolivierbouch Jul 23, 2025
c4147a1
Merge pull request #227 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
22abfe7
feat: updates
marcolivierbouch Jul 23, 2025
0557f3f
Merge pull request #228 from OpenAssistantGPT/feat/download-pdf-trans…
marcolivierbouch Jul 23, 2025
8cfac1f
Version Packages
github-actions[bot] Jul 23, 2025
c93620b
Merge pull request #229 from OpenAssistantGPT/changeset-release/main
marcolivierbouch Jul 23, 2025
f1d30fe
feat: update
marcolivierbouch Jul 23, 2025
e929330
Merge branch 'main' of github.com:OpenAssistantGPT/OpenAssistantGPT-S…
marcolivierbouch Jul 23, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .changeset/pretty-wolves-learn.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
'next-website': patch
'@openassistantgpt/react': patch
'openassistantgpt': patch
'@openassistantgpt/ui': patch
---

fix versions
2 changes: 1 addition & 1 deletion .github/workflows/release-snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ jobs:
with:
fetch-depth: 0

- name: Setup pnpm 8
- name: Setup pnpm 9
uses: pnpm/action-setup@v4
with:
version: 8.6.9
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
with:
fetch-depth: 0

- name: Setup pnpm 8
- name: Setup pnpm 9
uses: pnpm/action-setup@v4
with:
version: 8.6.9
Expand Down
6 changes: 3 additions & 3 deletions examples/next-website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
},
"dependencies": {
"@openassistantgpt/assistant": "^0.2.0",
"@openassistantgpt/react": "^0.3.0",
"@openassistantgpt/ui": "^0.3.0",
"@openassistantgpt/react": "^0.3.4",
"@openassistantgpt/ui": "^0.3.14",
"@radix-ui/react-dialog": "^1.1.1",
"@radix-ui/react-icons": "^1.3.0",
"@radix-ui/react-icons": "^1.3.2",
"@radix-ui/react-label": "^2.1.0",
"@radix-ui/react-slot": "^1.1.0",
"buffer": "^6.0.3",
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@
"publint": "turbo publint",
"test": "turbo test",
"ci:release": "turbo clean && turbo build && changeset publish",
"ci:version": "changeset version && node .github/scripts/cleanup-examples-changesets.mjs && pnpm install --no-frozen-lockfile",
"clean-examples": "node .github/scripts/cleanup-examples-changesets.mjs && pnpm install --no-frozen-lockfile",
"ci:version": "changeset version && node .github/scripts/cleanup-examples-changesets.mjs && pnpm install --prefer-offline || true",
"clean-examples": "node .github/scripts/cleanup-examples-changesets.mjs && pnpm install --prefer-offline || true",
"check-docs-links": "node ./check-docs-links.js"
},
"lint-staged": {
Expand Down
9 changes: 9 additions & 0 deletions packages/core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# core

## 0.3.15

### Patch Changes

- 22abfe7: Fix versions
- Updated dependencies [22abfe7]
- @openassistantgpt/[email protected]
- @openassistantgpt/[email protected]

## 0.3.14

### Patch Changes
Expand Down
2 changes: 1 addition & 1 deletion packages/core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openassistantgpt",
"version": "0.3.14",
"version": "0.3.15",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
Expand Down
6 changes: 6 additions & 0 deletions packages/react/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# @assistant

## 0.3.4

### Patch Changes

- 22abfe7: Fix versions

## 0.3.3

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/react/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@openassistantgpt/react",
"version": "0.3.3",
"version": "0.3.4",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
Expand All @@ -27,7 +27,7 @@
"dependencies": {
"@ai-sdk/provider-utils": "1.0.5",
"@ai-sdk/ui-utils": "0.0.20",
"@vitejs/plugin-react": "^4.3.1",
"@vitejs/plugin-react": "^4.3.4",
"ai": "^3.2.24",
"openai": "^4.52.7",
"swr": "2.2.5"
Expand Down
8 changes: 8 additions & 0 deletions packages/ui/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# @openassistantgpt/ui

## 0.3.14

### Patch Changes

- 22abfe7: Fix versions
- Updated dependencies [22abfe7]
- @openassistantgpt/[email protected]

## 0.3.13

### Patch Changes
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/components/chat-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,10 +125,10 @@ export function ChatHeader({
style={{ color: chatbot.chatHeaderTextColor }}
className="h-4 w-4"
/>
<span className="sr-only">Download Transcript</span>
<span className="sr-only">Download as PDF</span>
</Button>
</TooltipTrigger>
<TooltipContent>Download Transcript</TooltipContent>
<TooltipContent>Download as PDF</TooltipContent>
</Tooltip>
{withExitX && (
<Tooltip>
Expand Down
244 changes: 244 additions & 0 deletions packages/ui/components/chat-pdf-export.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
import React, { ReactNode } from 'react';
import {
Document,
Page,
Text,
View,
StyleSheet,
pdf,
} from '@react-pdf/renderer';
import { Message } from '@openassistantgpt/react';
import { ChatbotConfig } from '@/src/chatbot';

const styles = StyleSheet.create({
page: {
flexDirection: 'column',
backgroundColor: '#ffffff',
padding: 40,
fontFamily: 'Helvetica',
},
header: {
marginBottom: 30,
paddingBottom: 20,
borderBottom: '2 solid #e5e7eb',
},
title: {
fontSize: 24,
fontWeight: 'bold',
color: '#1f2937',
marginBottom: 5,
fontFamily: 'Helvetica-Bold',
},
subtitle: {
fontSize: 12,
color: '#6b7280',
marginBottom: 10,
fontFamily: 'Helvetica',
},
chatContainer: {
flexDirection: 'column',
gap: 16,
},
messageContainer: {
flexDirection: 'column',
marginBottom: 16,
break: false, // Prevent breaking this container across pages
},
userMessage: {
alignSelf: 'flex-end',
maxWidth: '75%',
wrap: false, // Keep the entire message together
alignItems: 'flex-end', // Align all content to the right within the container
},
assistantMessage: {
alignSelf: 'flex-start',
maxWidth: '85%',
wrap: false, // Keep the entire message together
alignItems: 'flex-start', // Align all content to the left within the container
},
messageHeader: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 6,
},
userBubble: {
backgroundColor: '#3b82f6',
color: '#ffffff',
padding: 12,
borderRadius: 18,
borderBottomRightRadius: 4,
break: false, // Prevent breaking the bubble across pages
},
assistantBubble: {
backgroundColor: '#f3f4f6',
color: '#1f2937',
padding: 12,
borderRadius: 18,
borderBottomLeftRadius: 4,
break: false, // Prevent breaking the bubble across pages
},
messageText: {
fontSize: 11,
lineHeight: 1.5,
fontFamily: 'Helvetica',
},
roleLabel: {
fontSize: 9,
fontWeight: 'bold',
color: '#6b7280',
marginBottom: 4,
textTransform: 'uppercase',
letterSpacing: 0.5,
fontFamily: 'Helvetica-Bold',
},
timestamp: {
fontSize: 8,
color: '#9ca3af',
marginTop: 4,
textAlign: 'right',
fontFamily: 'Helvetica',
},
footer: {
position: 'absolute',
bottom: 30,
left: 40,
right: 40,
textAlign: 'center',
color: '#9ca3af',
fontSize: 8,
borderTop: '1 solid #e5e7eb',
paddingTop: 10,
fontFamily: 'Helvetica',
},
pageNumber: {
position: 'absolute',
fontSize: 8,
bottom: 20,
left: 0,
right: 0,
textAlign: 'center',
color: '#9ca3af',
fontFamily: 'Helvetica',
},
});

interface ChatPDFDocumentProps {
messages: Message[];
chatbot: ChatbotConfig;
timestamp: string;
}

const ChatPDFDocument: React.FC<ChatPDFDocumentProps> = ({
messages,
chatbot,
timestamp,
}) => {
const formatMessageContent = (content: string) => {
// Remove markdown formatting for PDF
return content
.replace(/\*\*(.*?)\*\*/g, '$1') // Remove bold
.replace(/\*(.*?)\*/g, '$1') // Remove italic
.replace(/```[\s\S]*?```/g, '[Code Block]') // Replace code blocks
.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1') // Remove links but keep text
.replace(/#{1,6}\s/g, '') // Remove headers
.replace(/\【.*?】/g, '') // Remove any special annotations
.trim(); // Clean up whitespace
};

return (
<Document>
<Page size="A4" style={styles.page}>
{/* Header */}
<View style={styles.header}>
<Text style={styles.title}>Chat Conversation</Text>
<Text style={styles.subtitle}>
{chatbot.chatTitle || chatbot.name}
</Text>
<Text style={styles.subtitle}>Exported on {timestamp}</Text>
</View>

{/* Chat Content */}
<View style={styles.chatContainer}>
{/* Welcome Message */}
<View
style={[styles.messageContainer, styles.assistantMessage]}
wrap={false}
>
<Text style={styles.roleLabel}>Assistant</Text>
<View style={styles.assistantBubble}>
<Text style={styles.messageText}>
{formatMessageContent(chatbot.welcomeMessage)}
</Text>
</View>
</View>

{/* Chat Messages */}
{messages.map((message, index) => (
<View
key={`message-${index}`}
style={[
styles.messageContainer,
message.role === 'user'
? styles.userMessage
: styles.assistantMessage,
]}
wrap={false} // Prevent individual messages from breaking across pages
>
<Text style={styles.roleLabel}>
{message.role === 'user' ? 'You' : 'Assistant'}
</Text>
<View
style={
message.role === 'user'
? styles.userBubble
: styles.assistantBubble
}
>
<Text style={styles.messageText}>
{formatMessageContent(message.content)}
</Text>
</View>
</View>
))}
</View>

{/* Footer */}
<View style={styles.footer}>
<Text>
Generated by {chatbot.name || 'OpenAssistantGPT'} -{' '}
{chatbot.footerTextName || 'OpenAssistantGPT'}
</Text>
</View>

{/* Page Number */}
<Text
style={styles.pageNumber}
render={({ pageNumber, totalPages }) =>
`Page ${pageNumber} of ${totalPages}`
}
fixed
/>
</Page>
</Document>
);
};

export const generateChatPDF = async (
messages: Message[],
chatbot: ChatbotConfig,
): Promise<Blob> => {
const timestamp = new Date().toLocaleString();

const doc = (
<ChatPDFDocument
messages={messages}
chatbot={chatbot}
timestamp={timestamp}
/>
) as React.ReactElement;

const pdfBlob = await pdf(doc).toBlob();
return pdfBlob;
};

export default ChatPDFDocument;
Loading
Loading