@drawnagency/primitives 0.1.67 → 0.1.68
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/dist/chunk-4YEOTFVU.js +14 -0
- package/dist/{chunk-VU3XR362.js → chunk-6UDYJQL6.js} +1 -1
- package/dist/{chunk-7IMQVDDJ.js → chunk-EWKCEPMW.js} +1 -1
- package/dist/{chunk-XNGG5AGI.js → chunk-KWBM27UR.js} +1 -1
- package/dist/{chunk-TEYTLQVH.js → chunk-QKOIEWZ4.js} +33 -1
- package/dist/{chunk-4VMAZZXT.js → chunk-TYYCKVAW.js} +4 -4
- package/dist/{chunk-KM6HOW4H.js → chunk-VVK6ZRCN.js} +2 -2
- package/dist/{chunk-AFK45HX2.js → chunk-WNPMBFD6.js} +1 -1
- package/dist/{chunk-WJ7RZ6CC.js → chunk-WXVKX6PY.js} +1 -1
- package/dist/components/chat/ChatPanel.d.ts +31 -0
- package/dist/components/chat/ChatPanel.d.ts.map +1 -0
- package/dist/components/chat/ChatWidget.d.ts +11 -0
- package/dist/components/chat/ChatWidget.d.ts.map +1 -0
- package/dist/components/primitives/index.js +5 -5
- package/dist/components/sections/brand-guide.js +5 -5
- package/dist/components/sections/register-schemas.js +7 -7
- package/dist/components/sections/register.js +7 -7
- package/dist/components/shell/ChatbotConfigModal.d.ts +13 -0
- package/dist/components/shell/ChatbotConfigModal.d.ts.map +1 -0
- package/dist/components/shell/EditorShell.d.ts +2 -1
- package/dist/components/shell/EditorShell.d.ts.map +1 -1
- package/dist/index.js +12 -5
- package/dist/lib/index.d.ts +1 -0
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +6 -3
- package/dist/lib/platform-broker.d.ts +7 -0
- package/dist/lib/platform-broker.d.ts.map +1 -1
- package/dist/lib/platform-broker.js +27 -1
- package/dist/media/index.js +3 -3
- package/dist/schemas/index.js +6 -2
- package/dist/schemas/site-config.d.ts +30 -0
- package/dist/schemas/site-config.d.ts.map +1 -1
- package/dist/types/database.d.ts +48 -0
- package/dist/types/database.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/ChatPanel.tsx +152 -0
- package/src/components/chat/ChatWidget.tsx +38 -0
- package/src/components/shell/ChatbotConfigModal.tsx +152 -0
- package/src/components/shell/EditorShell.tsx +28 -1
- package/src/lib/index.ts +1 -0
- package/src/lib/platform-broker.ts +36 -0
- package/src/schemas/site-config.ts +36 -0
- package/src/types/database.ts +48 -0
- package/dist/chunk-ZGFAYZWB.js +0 -8
|
@@ -70,3 +70,39 @@ export async function platformBroker<T = unknown>(
|
|
|
70
70
|
|
|
71
71
|
throw lastError instanceof Error ? lastError : new Error("Platform broker unreachable");
|
|
72
72
|
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Streaming variant of platformBroker for SSE endpoints (the LLM broker).
|
|
76
|
+
* Same auth headers; retries only pre-stream connection failures — once bytes
|
|
77
|
+
* are flowing there is no safe retry. Non-2xx throws with the status ONLY
|
|
78
|
+
* (never the body: stream endpoints may proxy provider errors).
|
|
79
|
+
*/
|
|
80
|
+
export async function platformBrokerStream(
|
|
81
|
+
path: string,
|
|
82
|
+
body: unknown,
|
|
83
|
+
): Promise<ReadableStream<Uint8Array>> {
|
|
84
|
+
const apiUrl = env("PLATFORM_API_URL");
|
|
85
|
+
const apiKey = env("PLATFORM_API_KEY");
|
|
86
|
+
const siteId = env("PORTAL_SITE_ID");
|
|
87
|
+
const url = `${apiUrl}${path}`;
|
|
88
|
+
|
|
89
|
+
let lastError: unknown;
|
|
90
|
+
for (let attempt = 0; attempt < ATTEMPTS; attempt++) {
|
|
91
|
+
let res: Response;
|
|
92
|
+
try {
|
|
93
|
+
res = await fetch(url, {
|
|
94
|
+
method: "POST",
|
|
95
|
+
headers: { "x-api-key": apiKey, "x-site-id": siteId, "Content-Type": "application/json" },
|
|
96
|
+
body: JSON.stringify(body),
|
|
97
|
+
});
|
|
98
|
+
} catch (err) {
|
|
99
|
+
lastError = err;
|
|
100
|
+
if (attempt === ATTEMPTS - 1) throw err;
|
|
101
|
+
await sleep(RETRY_BASE_MS * 2 ** attempt);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
if (!res.ok || !res.body) throw new Error(`Platform broker error (${res.status})`);
|
|
105
|
+
return res.body;
|
|
106
|
+
}
|
|
107
|
+
throw lastError instanceof Error ? lastError : new Error("Platform broker unreachable");
|
|
108
|
+
}
|
|
@@ -132,6 +132,38 @@ export function normalizeSiteIndex(raw: unknown): SiteIndex {
|
|
|
132
132
|
return IndexSchema.parse(raw);
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
// Task ids share the audience-name slug rules (lowercase alnum/dash/underscore).
|
|
136
|
+
const ChatbotTaskIdSchema = z.string().min(1).max(32).regex(/^[a-z0-9](?:[a-z0-9_-]*[a-z0-9])?$/,
|
|
137
|
+
"Task id must be lowercase letters, numbers, dashes, or underscores");
|
|
138
|
+
|
|
139
|
+
export const ChatbotTaskSchema = z.object({
|
|
140
|
+
id: ChatbotTaskIdSchema,
|
|
141
|
+
label: z.string().min(1).max(60),
|
|
142
|
+
prompt: z.string().max(4_000),
|
|
143
|
+
// Audience names allowed to see this task; [] = all — same semantics as SectionMeta.access.
|
|
144
|
+
access: z.array(z.string()).default([]),
|
|
145
|
+
});
|
|
146
|
+
export type ChatbotTask = z.infer<typeof ChatbotTaskSchema>;
|
|
147
|
+
|
|
148
|
+
export const ChatbotConfigSchema = z
|
|
149
|
+
.object({
|
|
150
|
+
enabled: z.boolean().default(false),
|
|
151
|
+
systemPrompt: z.string().max(8_000).default(""),
|
|
152
|
+
// Audience names the widget is shown to; [] = all audiences.
|
|
153
|
+
audiences: z.array(z.string()).default([]),
|
|
154
|
+
tasks: z.array(ChatbotTaskSchema).max(20).default([]),
|
|
155
|
+
})
|
|
156
|
+
.superRefine((cfg, ctx) => {
|
|
157
|
+
const seen = new Set<string>();
|
|
158
|
+
for (const t of cfg.tasks) {
|
|
159
|
+
if (seen.has(t.id)) {
|
|
160
|
+
ctx.addIssue({ code: z.ZodIssueCode.custom, message: `Duplicate task id "${t.id}"` });
|
|
161
|
+
}
|
|
162
|
+
seen.add(t.id);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
export type ChatbotConfig = z.infer<typeof ChatbotConfigSchema>;
|
|
166
|
+
|
|
135
167
|
export const SiteConfigSchema = z.object({
|
|
136
168
|
siteName: z.string().default("Brand Portal"),
|
|
137
169
|
primaryColor: HexColorSchema.default("#009ca6"),
|
|
@@ -153,6 +185,10 @@ export const SiteConfigSchema = z.object({
|
|
|
153
185
|
.nullable()
|
|
154
186
|
.default(null),
|
|
155
187
|
media: MediaConfigSchema.default(MediaConfigSchema.parse({})),
|
|
188
|
+
// Brand chatbot config (editor-owned; the platform kill switch lives in the
|
|
189
|
+
// sites table, not here). Every field defaults so pre-existing
|
|
190
|
+
// site-config.json files keep parsing.
|
|
191
|
+
chatbot: ChatbotConfigSchema.default({ enabled: false, systemPrompt: "", audiences: [], tasks: [] }),
|
|
156
192
|
});
|
|
157
193
|
|
|
158
194
|
export type SiteConfig = z.infer<typeof SiteConfigSchema>;
|
package/src/types/database.ts
CHANGED
|
@@ -150,6 +150,41 @@ export type Database = {
|
|
|
150
150
|
},
|
|
151
151
|
]
|
|
152
152
|
}
|
|
153
|
+
chat_usage: {
|
|
154
|
+
Row: {
|
|
155
|
+
day: string
|
|
156
|
+
input_tokens: number
|
|
157
|
+
output_tokens: number
|
|
158
|
+
requests: number
|
|
159
|
+
site_id: string
|
|
160
|
+
updated_at: string
|
|
161
|
+
}
|
|
162
|
+
Insert: {
|
|
163
|
+
day: string
|
|
164
|
+
input_tokens?: number
|
|
165
|
+
output_tokens?: number
|
|
166
|
+
requests?: number
|
|
167
|
+
site_id: string
|
|
168
|
+
updated_at?: string
|
|
169
|
+
}
|
|
170
|
+
Update: {
|
|
171
|
+
day?: string
|
|
172
|
+
input_tokens?: number
|
|
173
|
+
output_tokens?: number
|
|
174
|
+
requests?: number
|
|
175
|
+
site_id?: string
|
|
176
|
+
updated_at?: string
|
|
177
|
+
}
|
|
178
|
+
Relationships: [
|
|
179
|
+
{
|
|
180
|
+
foreignKeyName: "chat_usage_site_id_fkey"
|
|
181
|
+
columns: ["site_id"]
|
|
182
|
+
isOneToOne: false
|
|
183
|
+
referencedRelation: "sites"
|
|
184
|
+
referencedColumns: ["id"]
|
|
185
|
+
},
|
|
186
|
+
]
|
|
187
|
+
}
|
|
153
188
|
deploy_status: {
|
|
154
189
|
Row: {
|
|
155
190
|
commit_sha: string | null
|
|
@@ -535,6 +570,7 @@ export type Database = {
|
|
|
535
570
|
}
|
|
536
571
|
sites: {
|
|
537
572
|
Row: {
|
|
573
|
+
chatbot_enabled: boolean
|
|
538
574
|
created_at: string | null
|
|
539
575
|
custom_domain: string | null
|
|
540
576
|
failed_step: string | null
|
|
@@ -550,6 +586,7 @@ export type Database = {
|
|
|
550
586
|
subdomain: string | null
|
|
551
587
|
}
|
|
552
588
|
Insert: {
|
|
589
|
+
chatbot_enabled?: boolean
|
|
553
590
|
created_at?: string | null
|
|
554
591
|
custom_domain?: string | null
|
|
555
592
|
failed_step?: string | null
|
|
@@ -565,6 +602,7 @@ export type Database = {
|
|
|
565
602
|
subdomain?: string | null
|
|
566
603
|
}
|
|
567
604
|
Update: {
|
|
605
|
+
chatbot_enabled?: boolean
|
|
568
606
|
created_at?: string | null
|
|
569
607
|
custom_domain?: string | null
|
|
570
608
|
failed_step?: string | null
|
|
@@ -642,6 +680,16 @@ export type Database = {
|
|
|
642
680
|
[_ in never]: never
|
|
643
681
|
}
|
|
644
682
|
Functions: {
|
|
683
|
+
chat_usage_hit: {
|
|
684
|
+
Args: {
|
|
685
|
+
p_day: string
|
|
686
|
+
p_input_tokens: number
|
|
687
|
+
p_output_tokens: number
|
|
688
|
+
p_requests: number
|
|
689
|
+
p_site_id: string
|
|
690
|
+
}
|
|
691
|
+
Returns: undefined
|
|
692
|
+
}
|
|
645
693
|
get_user_id_by_email: { Args: { lookup_email: string }; Returns: string }
|
|
646
694
|
is_site_member: { Args: { p_site_id: string }; Returns: boolean }
|
|
647
695
|
is_site_owner: { Args: { p_site_id: string }; Returns: boolean }
|