@promptbook/cli 0.104.0-5 โ 0.104.0-6
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/src/app/agents/[agentName]/AgentProfileWrapper.tsx +3 -2
- package/apps/agents-server/src/app/agents/[agentName]/_utils.ts +6 -2
- package/apps/agents-server/src/app/agents/[agentName]/code/page.tsx +14 -8
- package/apps/agents-server/src/app/agents/[agentName]/images/icon-256.png/route.tsx +5 -2
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-phone.png/route.tsx +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/integration/page.tsx +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/links/page.tsx +2 -2
- package/apps/agents-server/src/app/agents/[agentName]/opengraph-image.tsx +6 -2
- package/apps/agents-server/src/app/agents/[agentName]/page.tsx +7 -4
- package/apps/agents-server/src/app/agents/[agentName]/system-message/page.tsx +2 -1
- package/apps/agents-server/src/app/api/emails/incoming/sendgrid/route.ts +48 -0
- package/apps/agents-server/src/components/AgentProfile/AgentProfile.tsx +10 -2
- package/apps/agents-server/src/components/Homepage/AgentCard.tsx +2 -1
- package/apps/agents-server/src/message-providers/email/sendgrid/parseInboundSendgridEmail.ts +49 -0
- package/apps/agents-server/src/utils/content/extractBodyContentFromHtml.ts +19 -0
- package/esm/index.es.js +1 -43
- package/esm/index.es.js.map +1 -1
- package/esm/typings/src/book-2.0/agent-source/createAgentModelRequirements.d.ts +6 -6
- package/esm/typings/src/book-2.0/utils/generatePlaceholderAgentProfileImageUrl.d.ts +3 -3
- package/esm/typings/src/types/typeAliases.d.ts +4 -0
- package/esm/typings/src/version.d.ts +1 -1
- package/package.json +1 -1
- package/umd/index.umd.js +1 -43
- package/umd/index.umd.js.map +1 -1
- package/esm/typings/src/book-2.0/utils/generateGravatarUrl.d.ts +0 -10
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { AgentBasicInformation } from '@promptbook-local/types';
|
|
3
|
+
import { AgentBasicInformation, string_agent_name } from '@promptbook-local/types';
|
|
4
4
|
import { AgentProfile } from '../../../components/AgentProfile/AgentProfile';
|
|
5
5
|
import { AgentOptionsMenu } from './AgentOptionsMenu';
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ type AgentProfileWrapperProps = {
|
|
|
8
8
|
agent: AgentBasicInformation;
|
|
9
9
|
agentUrl: string;
|
|
10
10
|
agentEmail: string;
|
|
11
|
-
agentName:
|
|
11
|
+
agentName: string_agent_name;
|
|
12
12
|
brandColorHex: string;
|
|
13
13
|
isAdmin: boolean;
|
|
14
14
|
isHeadless: boolean;
|
|
@@ -27,6 +27,7 @@ export function AgentProfileWrapper(props: AgentProfileWrapperProps) {
|
|
|
27
27
|
<AgentProfile
|
|
28
28
|
agent={agent}
|
|
29
29
|
agentUrl={agentUrl}
|
|
30
|
+
permanentId={permanentId || agentName}
|
|
30
31
|
agentEmail={agentEmail}
|
|
31
32
|
isHeadless={isHeadless}
|
|
32
33
|
renderMenu={({ onShowQrCode }) => (
|
|
@@ -13,7 +13,11 @@ export async function getAgentName(params: Promise<{ agentName: string }>) {
|
|
|
13
13
|
export async function getAgentProfile(agentName: string) {
|
|
14
14
|
const collection = await $provideAgentCollectionForServer();
|
|
15
15
|
const agentSource = await collection.getAgentSource(agentName);
|
|
16
|
-
|
|
16
|
+
const agentProfile = parseAgentSource(agentSource);
|
|
17
|
+
|
|
18
|
+
console.log('!!!!', { agentSource, agentProfile });
|
|
19
|
+
|
|
20
|
+
return agentProfile;
|
|
17
21
|
}
|
|
18
22
|
|
|
19
23
|
export async function isAgentDeleted(agentName: string): Promise<boolean> {
|
|
@@ -33,5 +37,5 @@ export async function isAgentDeleted(agentName: string): Promise<boolean> {
|
|
|
33
37
|
}
|
|
34
38
|
|
|
35
39
|
/**
|
|
36
|
-
* TODO: Split to multiple files
|
|
40
|
+
* TODO: Split to multiple files, refactor
|
|
37
41
|
*/
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import Editor from '@monaco-editor/react';
|
|
4
|
+
import { generatePlaceholderAgentProfileImageUrl } from '@promptbook-local/core';
|
|
5
|
+
import { AgentBasicInformation } from '@promptbook-local/types';
|
|
4
6
|
import { ArrowLeftIcon, ChevronDownIcon, CodeIcon } from 'lucide-react';
|
|
5
7
|
import Link from 'next/link';
|
|
6
8
|
import { useCallback, useEffect, useState } from 'react';
|
|
@@ -29,7 +31,7 @@ function getLanguageFromTranspiler(transpilerName?: string): string {
|
|
|
29
31
|
|
|
30
32
|
export default function AgentCodePage({ params }: { params: Promise<{ agentName: string }> }) {
|
|
31
33
|
const [agentName, setAgentName] = useState<string>('');
|
|
32
|
-
const [agentProfile, setAgentProfile] = useState<
|
|
34
|
+
const [agentProfile, setAgentProfile] = useState<AgentBasicInformation | null>(null);
|
|
33
35
|
const [transpilers, setTranspilers] = useState<Transpiler[]>([]);
|
|
34
36
|
const [selectedTranspiler, setSelectedTranspiler] = useState<Transpiler | null>(null);
|
|
35
37
|
const [transpiledCode, setTranspiledCode] = useState<string>('');
|
|
@@ -114,13 +116,17 @@ export default function AgentCodePage({ params }: { params: Promise<{ agentName:
|
|
|
114
116
|
{/* Header */}
|
|
115
117
|
<div className="p-6 border-b border-gray-200 flex items-center gap-4">
|
|
116
118
|
{/* eslint-disable @typescript-eslint/no-explicit-any, @next/next/no-img-element */}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
|
|
120
|
+
<img
|
|
121
|
+
src={
|
|
122
|
+
agentProfile.meta.image ||
|
|
123
|
+
agentProfile.permanentId ||
|
|
124
|
+
generatePlaceholderAgentProfileImageUrl(agentName)
|
|
125
|
+
}
|
|
126
|
+
alt={agentProfile.meta.fullname || agentName}
|
|
127
|
+
className="w-16 h-16 rounded-full object-cover border-2 border-gray-200"
|
|
128
|
+
/>
|
|
129
|
+
|
|
124
130
|
<div className="flex-1">
|
|
125
131
|
{/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
|
|
126
132
|
<h1 className="text-2xl font-bold text-gray-900">
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
1
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
2
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
3
|
import { ImageResponse } from 'next/og';
|
|
4
4
|
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
@@ -45,7 +45,10 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
45
45
|
>
|
|
46
46
|
{/* Note: `next/image` is not working propperly with `next/og` */}
|
|
47
47
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
|
48
|
-
<img
|
|
48
|
+
<img
|
|
49
|
+
src={agentProfile.meta.image || agentProfile.permanentId ||generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
50
|
+
alt="Agent Icon"
|
|
51
|
+
/>
|
|
49
52
|
</div>
|
|
50
53
|
</div>
|
|
51
54
|
),
|
package/apps/agents-server/src/app/agents/[agentName]/images/screenshot-fullhd.png/route.tsx
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
1
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
2
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
3
|
import { ImageResponse } from 'next/og';
|
|
4
4
|
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
@@ -51,7 +51,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
51
51
|
backgroundColor: agentColor.toHex(),
|
|
52
52
|
borderRadius: '50%',
|
|
53
53
|
}}
|
|
54
|
-
src={agentProfile.meta.image
|
|
54
|
+
src={agentProfile.meta.image || agentProfile.permanentId ||generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
55
55
|
alt="Agent Icon"
|
|
56
56
|
/>
|
|
57
57
|
</div>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
1
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
2
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
3
|
import { ImageResponse } from 'next/og';
|
|
4
4
|
import { assertsError } from '../../../../../../../../src/errors/assertsError';
|
|
@@ -51,7 +51,7 @@ export async function GET(request: Request, { params }: { params: Promise<{ agen
|
|
|
51
51
|
backgroundColor: agentColor.toHex(),
|
|
52
52
|
borderRadius: '50%',
|
|
53
53
|
}}
|
|
54
|
-
src={agentProfile.meta.image
|
|
54
|
+
src={agentProfile.meta.image || agentProfile.permanentId ||generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
55
55
|
alt="Agent Icon"
|
|
56
56
|
/>
|
|
57
57
|
</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';
|
|
@@ -187,7 +187,7 @@ export default async function AgentIntegrationPage({ params }: { params: Promise
|
|
|
187
187
|
{agentProfile.meta.image && (
|
|
188
188
|
// eslint-disable-next-line @next/next/no-img-element
|
|
189
189
|
<img
|
|
190
|
-
src={agentProfile.meta.image
|
|
190
|
+
src={agentProfile.meta.image || agentProfile.permanentId ||generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
191
191
|
alt={agentProfile.meta.fullname || agentName}
|
|
192
192
|
className="w-16 h-16 rounded-full object-cover border-2"
|
|
193
193
|
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';
|
|
@@ -56,7 +56,7 @@ export default async function AgentLinksPage({ params }: { params: Promise<{ age
|
|
|
56
56
|
{agentProfile.meta.image && (
|
|
57
57
|
// eslint-disable-next-line @next/next/no-img-element
|
|
58
58
|
<img
|
|
59
|
-
src={agentProfile.meta.image
|
|
59
|
+
src={agentProfile.meta.image || agentProfile.permanentId || generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
60
60
|
alt={agentProfile.meta.fullname || agentName}
|
|
61
61
|
className="w-16 h-16 rounded-full object-cover border-2"
|
|
62
62
|
style={{ borderColor: primaryColor }}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
1
|
+
import { generatePlaceholderAgentProfileImageUrl, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
2
2
|
import { serializeError } from '@promptbook-local/utils';
|
|
3
3
|
import { ImageResponse } from 'next/og';
|
|
4
4
|
import { assertsError } from '../../../../../../src/errors/assertsError';
|
|
@@ -54,7 +54,11 @@ export default async function Image({ params }: { params: Promise<{ agentName: s
|
|
|
54
54
|
backgroundColor: agentColor.toHex(),
|
|
55
55
|
borderRadius: '50%',
|
|
56
56
|
}}
|
|
57
|
-
src={
|
|
57
|
+
src={
|
|
58
|
+
agentProfile.meta.image ||
|
|
59
|
+
agentProfile.permanentId ||
|
|
60
|
+
generatePlaceholderAgentProfileImageUrl(agentProfile.permanentId || agentName)
|
|
61
|
+
}
|
|
58
62
|
alt="Agent Icon"
|
|
59
63
|
/>
|
|
60
64
|
</div>
|
|
@@ -3,17 +3,16 @@
|
|
|
3
3
|
import { $provideServer } from '@/src/tools/$provideServer';
|
|
4
4
|
import { isUserAdmin } from '@/src/utils/isUserAdmin';
|
|
5
5
|
import { saturate } from '@promptbook-local/color';
|
|
6
|
-
import { PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
7
|
-
import { NotFoundError } from '@promptbook-local/core';
|
|
6
|
+
import { generatePlaceholderAgentProfileImageUrl, NotFoundError, PROMPTBOOK_COLOR } from '@promptbook-local/core';
|
|
8
7
|
import { notFound } from 'next/navigation';
|
|
9
8
|
import { Color } from '../../../../../../src/utils/color/Color';
|
|
9
|
+
import { DeletedAgentBanner } from '../../../components/DeletedAgentBanner';
|
|
10
10
|
import { getAgentName, getAgentProfile, isAgentDeleted } from './_utils';
|
|
11
11
|
import { getAgentLinks } from './agentLinks';
|
|
12
12
|
import { AgentProfileChat } from './AgentProfileChat';
|
|
13
13
|
import { AgentProfileWrapper } from './AgentProfileWrapper';
|
|
14
14
|
import { generateAgentMetadata } from './generateAgentMetadata';
|
|
15
15
|
import { ServiceWorkerRegister } from './ServiceWorkerRegister';
|
|
16
|
-
import { DeletedAgentBanner } from '../../../components/DeletedAgentBanner';
|
|
17
16
|
|
|
18
17
|
export const generateMetadata = generateAgentMetadata;
|
|
19
18
|
|
|
@@ -96,7 +95,11 @@ export default async function AgentPage({
|
|
|
96
95
|
agentName={agentName}
|
|
97
96
|
fullname={fullname}
|
|
98
97
|
brandColorHex={brandColorHex}
|
|
99
|
-
avatarSrc={
|
|
98
|
+
avatarSrc={
|
|
99
|
+
agentProfile.meta.image ||
|
|
100
|
+
agentProfile.permanentId ||
|
|
101
|
+
generatePlaceholderAgentProfileImageUrl(agentName)
|
|
102
|
+
}
|
|
100
103
|
isDeleted={isDeleted}
|
|
101
104
|
/>
|
|
102
105
|
</AgentProfileWrapper>
|
|
@@ -8,6 +8,7 @@ import { notFound } from 'next/navigation';
|
|
|
8
8
|
import { $sideEffect } from '../../../../../../../src/utils/organization/$sideEffect';
|
|
9
9
|
import { getAgentName, getAgentProfile } from '../_utils';
|
|
10
10
|
import { generateAgentMetadata } from '../generateAgentMetadata';
|
|
11
|
+
import { generatePlaceholderAgentProfileImageUrl } from '@promptbook-local/core';
|
|
11
12
|
|
|
12
13
|
export const generateMetadata = generateAgentMetadata;
|
|
13
14
|
|
|
@@ -44,7 +45,7 @@ export default async function AgentSystemMessagePage({ params }: { params: Promi
|
|
|
44
45
|
{agentProfile.meta.image && (
|
|
45
46
|
// eslint-disable-next-line @next/next/no-img-element
|
|
46
47
|
<img
|
|
47
|
-
src={agentProfile.meta.image
|
|
48
|
+
src={agentProfile.meta.image|| agentProfile.permanentId ||generatePlaceholderAgentProfileImageUrl(agentName)}
|
|
48
49
|
alt={agentProfile.meta.fullname || agentName}
|
|
49
50
|
className="w-16 h-16 rounded-full object-cover border-2 border-gray-200"
|
|
50
51
|
/>
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { $getTableName } from '../../../../../database/$getTableName';
|
|
2
|
+
import { $provideSupabaseForServer } from '../../../../../database/$provideSupabaseForServer';
|
|
3
|
+
import { parseInboundSendgridEmail } from '../../../../../message-providers/email/sendgrid/parseInboundSendgridEmail';
|
|
4
|
+
import { NextRequest, NextResponse } from 'next/server';
|
|
5
|
+
|
|
6
|
+
export async function POST(request: NextRequest) {
|
|
7
|
+
try {
|
|
8
|
+
const formData = await request.formData();
|
|
9
|
+
const rawEmail = formData.get('email');
|
|
10
|
+
|
|
11
|
+
if (typeof rawEmail !== 'string') {
|
|
12
|
+
return NextResponse.json({ error: 'Missing email field' }, { status: 400 });
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const email = await parseInboundSendgridEmail(rawEmail);
|
|
16
|
+
|
|
17
|
+
const supabase = await $provideSupabaseForServer();
|
|
18
|
+
const { error } = await supabase
|
|
19
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
20
|
+
.from(await $getTableName('Message'))
|
|
21
|
+
.insert({
|
|
22
|
+
channel: 'EMAIL',
|
|
23
|
+
direction: 'INBOUND',
|
|
24
|
+
sender: email.sender,
|
|
25
|
+
recipients: email.recipients,
|
|
26
|
+
content: email.content,
|
|
27
|
+
metadata: {
|
|
28
|
+
subject: email.subject,
|
|
29
|
+
cc: email.cc,
|
|
30
|
+
...email.metadata,
|
|
31
|
+
},
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
} as any);
|
|
34
|
+
|
|
35
|
+
if (error) {
|
|
36
|
+
console.error('Failed to insert message', error);
|
|
37
|
+
return NextResponse.json({ error: error.message }, { status: 500 });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return NextResponse.json({ success: true });
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error processing inbound email', error);
|
|
43
|
+
return NextResponse.json(
|
|
44
|
+
{ error: error instanceof Error ? error.message : 'Unknown error' },
|
|
45
|
+
{ status: 500 },
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { generatePlaceholderAgentProfileImageUrl } from '@promptbook-local/core';
|
|
4
|
+
import { AgentBasicInformation, string_agent_permanent_id } from '@promptbook-local/types';
|
|
4
5
|
import { RepeatIcon } from 'lucide-react';
|
|
5
6
|
import { useState } from 'react';
|
|
6
7
|
import { AgentQrCode } from './AgentQrCode';
|
|
@@ -13,6 +14,11 @@ type AgentProfileProps = {
|
|
|
13
14
|
*/
|
|
14
15
|
readonly agent: AgentBasicInformation;
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* The permanent ID of the agent
|
|
19
|
+
*/
|
|
20
|
+
readonly permanentId: string_agent_permanent_id;
|
|
21
|
+
|
|
16
22
|
/**
|
|
17
23
|
* URL of the agent page
|
|
18
24
|
*
|
|
@@ -58,16 +64,18 @@ export function AgentProfile(props: AgentProfileProps) {
|
|
|
58
64
|
agent,
|
|
59
65
|
agentUrl = '',
|
|
60
66
|
agentEmail = '',
|
|
67
|
+
permanentId,
|
|
61
68
|
renderMenu,
|
|
62
69
|
children,
|
|
63
70
|
actions,
|
|
64
71
|
isHeadless = false,
|
|
65
72
|
className,
|
|
66
73
|
} = props;
|
|
74
|
+
console.log('!!!!', { agent });
|
|
67
75
|
const { meta, agentName } = agent;
|
|
68
76
|
const fullname = (meta.fullname as string) || agentName || 'Agent';
|
|
69
77
|
const personaDescription = agent.personaDescription || '';
|
|
70
|
-
const imageUrl =
|
|
78
|
+
const imageUrl = meta.image || generatePlaceholderAgentProfileImageUrl(permanentId);
|
|
71
79
|
|
|
72
80
|
const [isQrModalOpen, setIsQrModalOpen] = useState(false);
|
|
73
81
|
const [isFlipped, setIsFlipped] = useState(false);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
+
import { generatePlaceholderAgentProfileImageUrl } from '@promptbook-local/core';
|
|
3
4
|
import { really_any } from '@promptbook-local/types';
|
|
4
5
|
import { EyeIcon, EyeOffIcon, RotateCcwIcon } from 'lucide-react';
|
|
5
6
|
import Link from 'next/link';
|
|
@@ -32,7 +33,7 @@ export function AgentCard({
|
|
|
32
33
|
}: AgentCardProps) {
|
|
33
34
|
const { meta, agentName } = agent;
|
|
34
35
|
const fullname = (meta.fullname as string) || agentName || 'Agent';
|
|
35
|
-
const imageUrl =
|
|
36
|
+
const imageUrl = meta.image || generatePlaceholderAgentProfileImageUrl(agentName);
|
|
36
37
|
const personaDescription = agent.personaDescription || '';
|
|
37
38
|
|
|
38
39
|
const { brandColorLightHex, brandColorDarkHex, backgroundImage } = useAgentBackground(meta.color);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { string_markdown } from '@promptbook-local/types';
|
|
2
|
+
import { simpleParser } from 'mailparser';
|
|
3
|
+
import TurndownService from 'turndown';
|
|
4
|
+
import { extractBodyContentFromHtml } from '../../../utils/content/extractBodyContentFromHtml';
|
|
5
|
+
import type { InboundEmail } from '../_common/Email';
|
|
6
|
+
import { parseEmailAddress } from '../_common/utils/parseEmailAddress';
|
|
7
|
+
import { parseEmailAddresses } from '../_common/utils/parseEmailAddresses';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Function parseInboundSendgridEmail will parse raw inbound email from Sendgrid and return Email object
|
|
11
|
+
*/
|
|
12
|
+
export async function parseInboundSendgridEmail(rawEmail: string): Promise<InboundEmail> {
|
|
13
|
+
const parsedEmail = await simpleParser(rawEmail);
|
|
14
|
+
|
|
15
|
+
const toArray = !Array.isArray(parsedEmail.to)
|
|
16
|
+
? parsedEmail.to === undefined
|
|
17
|
+
? []
|
|
18
|
+
: [parsedEmail.to]
|
|
19
|
+
: parsedEmail.to;
|
|
20
|
+
const to = toArray.flatMap((_) => parseEmailAddresses(_.text));
|
|
21
|
+
|
|
22
|
+
const ccArray = !Array.isArray(parsedEmail.cc)
|
|
23
|
+
? parsedEmail.cc === undefined
|
|
24
|
+
? []
|
|
25
|
+
: [parsedEmail.cc]
|
|
26
|
+
: parsedEmail.cc;
|
|
27
|
+
const cc = ccArray.flatMap((_) => parseEmailAddresses(_.text));
|
|
28
|
+
|
|
29
|
+
const turndownService = new TurndownService();
|
|
30
|
+
|
|
31
|
+
const content = (parsedEmail.html
|
|
32
|
+
? turndownService.turndown(extractBodyContentFromHtml(parsedEmail.html))
|
|
33
|
+
: parsedEmail.text || '') as string_markdown;
|
|
34
|
+
|
|
35
|
+
const email: InboundEmail = {
|
|
36
|
+
channel: 'EMAIL',
|
|
37
|
+
direction: 'INBOUND',
|
|
38
|
+
sender: parseEmailAddress(parsedEmail.from?.text || '').fullEmail,
|
|
39
|
+
recipients: to.map((_) => _.fullEmail),
|
|
40
|
+
cc,
|
|
41
|
+
subject: parsedEmail.subject || '',
|
|
42
|
+
content,
|
|
43
|
+
attachments: [
|
|
44
|
+
/* <- TODO: [๐ฏ] Parse attachments */
|
|
45
|
+
],
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
return email;
|
|
49
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { string_html } from '@promptbook-local/types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extract the first heading from HTML
|
|
5
|
+
*
|
|
6
|
+
* @param contentText HTML
|
|
7
|
+
* @returns heading
|
|
8
|
+
*/
|
|
9
|
+
export function extractBodyContentFromHtml(html: string_html): string_html {
|
|
10
|
+
// Note: Not using DOMParser, because it's overkill for this simple task
|
|
11
|
+
|
|
12
|
+
const match = html.match(/<body[^>]*>(?<bodyContent>[\s\S]*)<\/body>/s);
|
|
13
|
+
|
|
14
|
+
if (!match) {
|
|
15
|
+
return html;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
return match.groups!.bodyContent!;
|
|
19
|
+
}
|
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-6';
|
|
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
|
|
@@ -26463,44 +26463,6 @@ async function createAgentModelRequirementsWithCommitments(agentSource, modelNam
|
|
|
26463
26463
|
};
|
|
26464
26464
|
}
|
|
26465
26465
|
|
|
26466
|
-
/**
|
|
26467
|
-
* Generates a gravatar URL based on agent name for fallback avatar
|
|
26468
|
-
*
|
|
26469
|
-
* @param agentName The agent name to generate avatar for
|
|
26470
|
-
* @returns Gravatar URL
|
|
26471
|
-
*
|
|
26472
|
-
* @private - [๐คน] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
|
|
26473
|
-
*/
|
|
26474
|
-
function generateGravatarUrl(agentName) {
|
|
26475
|
-
// Use a default name if none provided
|
|
26476
|
-
const safeName = agentName || 'Anonymous Agent';
|
|
26477
|
-
// Create a simple hash from the name for consistent avatar
|
|
26478
|
-
let hash = 0;
|
|
26479
|
-
for (let i = 0; i < safeName.length; i++) {
|
|
26480
|
-
const char = safeName.charCodeAt(i);
|
|
26481
|
-
hash = (hash << 5) - hash + char;
|
|
26482
|
-
hash = hash & hash; // Convert to 32bit integer
|
|
26483
|
-
}
|
|
26484
|
-
const avatarId = Math.abs(hash).toString();
|
|
26485
|
-
return `https://www.gravatar.com/avatar/${avatarId}?default=robohash&size=200&rating=x`;
|
|
26486
|
-
}
|
|
26487
|
-
|
|
26488
|
-
/**
|
|
26489
|
-
* Generates an image for the agent to use as profile image
|
|
26490
|
-
*
|
|
26491
|
-
* @param agentName The agent name to generate avatar for
|
|
26492
|
-
* @returns The placeholder profile image URL for the agent
|
|
26493
|
-
*
|
|
26494
|
-
* @public exported from `@promptbook/core`
|
|
26495
|
-
*/
|
|
26496
|
-
function generatePlaceholderAgentProfileImageUrl(agentName) {
|
|
26497
|
-
// Note: [๐คน] The fact that profile image is Gravatar is just implementation detail which should be hidden for consumer
|
|
26498
|
-
return generateGravatarUrl(agentName);
|
|
26499
|
-
}
|
|
26500
|
-
/**
|
|
26501
|
-
* TODO: [๐คน] Figure out best placeholder image generator https://i.pravatar.cc/1000?u=568
|
|
26502
|
-
*/
|
|
26503
|
-
|
|
26504
26466
|
/**
|
|
26505
26467
|
* Computes SHA-256 hash of the agent source
|
|
26506
26468
|
*
|
|
@@ -26598,10 +26560,6 @@ function parseAgentSource(agentSource) {
|
|
|
26598
26560
|
const metaType = normalizeTo_camelCase(metaTypeRaw);
|
|
26599
26561
|
meta[metaType] = spaceTrim$2(commitment.content.substring(metaTypeRaw.length));
|
|
26600
26562
|
}
|
|
26601
|
-
// Generate gravatar fallback if no meta image specified
|
|
26602
|
-
if (!meta.image) {
|
|
26603
|
-
meta.image = generatePlaceholderAgentProfileImageUrl(parseResult.agentName || '!!');
|
|
26604
|
-
}
|
|
26605
26563
|
// Generate fullname fallback if no meta fullname specified
|
|
26606
26564
|
if (!meta.fullname) {
|
|
26607
26565
|
meta.fullname = parseResult.agentName || createDefaultAgentName(agentSource);
|