@frankieai/core 0.1.0

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.
@@ -0,0 +1,377 @@
1
+ import { z } from 'zod';
2
+
3
+ /**
4
+ * Tenant configuration. One config == one embedded agent. Everything a
5
+ * customer needs to change to make Frankie theirs lives here, so the code
6
+ * itself stays generic.
7
+ */
8
+ declare const widgetThemeSchema: z.ZodPrefault<z.ZodObject<{
9
+ primary: z.ZodOptional<z.ZodString>;
10
+ primaryForeground: z.ZodOptional<z.ZodString>;
11
+ background: z.ZodOptional<z.ZodString>;
12
+ foreground: z.ZodOptional<z.ZodString>;
13
+ muted: z.ZodOptional<z.ZodString>;
14
+ border: z.ZodOptional<z.ZodString>;
15
+ radius: z.ZodOptional<z.ZodString>;
16
+ fontFamily: z.ZodOptional<z.ZodString>;
17
+ mode: z.ZodDefault<z.ZodEnum<{
18
+ light: "light";
19
+ dark: "dark";
20
+ system: "system";
21
+ }>>;
22
+ }, z.core.$strip>>;
23
+ declare const thinkingLevelSchema: z.ZodEnum<{
24
+ minimal: "minimal";
25
+ low: "low";
26
+ medium: "medium";
27
+ high: "high";
28
+ xhigh: "xhigh";
29
+ max: "max";
30
+ }>;
31
+ declare const modelConfigSchema: z.ZodObject<{
32
+ provider: z.ZodDefault<z.ZodString>;
33
+ model: z.ZodDefault<z.ZodString>;
34
+ apiKeyEnv: z.ZodDefault<z.ZodString>;
35
+ baseUrl: z.ZodOptional<z.ZodString>;
36
+ maxTokens: z.ZodDefault<z.ZodNumber>;
37
+ temperature: z.ZodDefault<z.ZodNumber>;
38
+ thinkingLevel: z.ZodDefault<z.ZodEnum<{
39
+ minimal: "minimal";
40
+ low: "low";
41
+ medium: "medium";
42
+ high: "high";
43
+ xhigh: "xhigh";
44
+ max: "max";
45
+ }>>;
46
+ streamReasoning: z.ZodDefault<z.ZodBoolean>;
47
+ }, z.core.$strip>;
48
+ declare const mcpServerSchema: z.ZodObject<{
49
+ name: z.ZodString;
50
+ transport: z.ZodDefault<z.ZodEnum<{
51
+ http: "http";
52
+ sse: "sse";
53
+ }>>;
54
+ url: z.ZodString;
55
+ headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
56
+ forwardUserTokenAs: z.ZodOptional<z.ZodString>;
57
+ forwardUserClaims: z.ZodDefault<z.ZodArray<z.ZodString>>;
58
+ }, z.core.$strip>;
59
+ /**
60
+ * An HTTP API described by an OpenAPI document, turned into tools directly.
61
+ *
62
+ * This is the "no MCP server to write" path: point Frankie at a spec, name the
63
+ * operations the agent may use, and it builds the tools at startup.
64
+ */
65
+ declare const apiSourceSchema: z.ZodObject<{
66
+ name: z.ZodString;
67
+ spec: z.ZodString;
68
+ baseUrl: z.ZodOptional<z.ZodString>;
69
+ operations: z.ZodDefault<z.ZodArray<z.ZodString>>;
70
+ includePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
71
+ methods: z.ZodDefault<z.ZodArray<z.ZodEnum<{
72
+ GET: "GET";
73
+ POST: "POST";
74
+ PUT: "PUT";
75
+ PATCH: "PATCH";
76
+ DELETE: "DELETE";
77
+ }>>>;
78
+ headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
79
+ forwardUserTokenAs: z.ZodOptional<z.ZodString>;
80
+ forwardUserClaims: z.ZodDefault<z.ZodArray<z.ZodString>>;
81
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
82
+ maxResponseChars: z.ZodDefault<z.ZodNumber>;
83
+ }, z.core.$strip>;
84
+ declare const toolPolicySchema: z.ZodObject<{
85
+ allow: z.ZodDefault<z.ZodArray<z.ZodString>>;
86
+ deny: z.ZodDefault<z.ZodArray<z.ZodString>>;
87
+ denyByDefault: z.ZodDefault<z.ZodBoolean>;
88
+ }, z.core.$strip>;
89
+ declare const agentConfigSchema: z.ZodObject<{
90
+ systemPrompt: z.ZodDefault<z.ZodString>;
91
+ greeting: z.ZodDefault<z.ZodString>;
92
+ suggestedPrompts: z.ZodDefault<z.ZodArray<z.ZodString>>;
93
+ maxTurns: z.ZodDefault<z.ZodNumber>;
94
+ maxBudgetUsd: z.ZodOptional<z.ZodNumber>;
95
+ tools: z.ZodPrefault<z.ZodObject<{
96
+ allow: z.ZodDefault<z.ZodArray<z.ZodString>>;
97
+ deny: z.ZodDefault<z.ZodArray<z.ZodString>>;
98
+ denyByDefault: z.ZodDefault<z.ZodBoolean>;
99
+ }, z.core.$strip>>;
100
+ showToolActivity: z.ZodDefault<z.ZodBoolean>;
101
+ }, z.core.$strip>;
102
+ declare const authConfigSchema: z.ZodObject<{
103
+ publishableKey: z.ZodString;
104
+ allowedOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
105
+ allowAnonymous: z.ZodDefault<z.ZodBoolean>;
106
+ jwtSecretEnv: z.ZodDefault<z.ZodString>;
107
+ jwksUrl: z.ZodOptional<z.ZodString>;
108
+ jwtIssuer: z.ZodOptional<z.ZodString>;
109
+ jwtAudience: z.ZodOptional<z.ZodString>;
110
+ sessionTtlSeconds: z.ZodDefault<z.ZodNumber>;
111
+ sessionSecretEnv: z.ZodDefault<z.ZodString>;
112
+ }, z.core.$strip>;
113
+ declare const limitsConfigSchema: z.ZodObject<{
114
+ messagesPerWindow: z.ZodDefault<z.ZodNumber>;
115
+ windowSeconds: z.ZodDefault<z.ZodNumber>;
116
+ sessionsPerIpPerWindow: z.ZodDefault<z.ZodNumber>;
117
+ turnTimeoutMs: z.ZodDefault<z.ZodNumber>;
118
+ }, z.core.$strip>;
119
+ declare const brandingConfigSchema: z.ZodObject<{
120
+ name: z.ZodDefault<z.ZodString>;
121
+ tagline: z.ZodOptional<z.ZodString>;
122
+ avatarUrl: z.ZodOptional<z.ZodString>;
123
+ launcherLabel: z.ZodDefault<z.ZodString>;
124
+ }, z.core.$strip>;
125
+ declare const frankieConfigSchema: z.ZodObject<{
126
+ tenantId: z.ZodString;
127
+ branding: z.ZodPrefault<z.ZodObject<{
128
+ name: z.ZodDefault<z.ZodString>;
129
+ tagline: z.ZodOptional<z.ZodString>;
130
+ avatarUrl: z.ZodOptional<z.ZodString>;
131
+ launcherLabel: z.ZodDefault<z.ZodString>;
132
+ }, z.core.$strip>>;
133
+ theme: z.ZodPrefault<z.ZodObject<{
134
+ primary: z.ZodOptional<z.ZodString>;
135
+ primaryForeground: z.ZodOptional<z.ZodString>;
136
+ background: z.ZodOptional<z.ZodString>;
137
+ foreground: z.ZodOptional<z.ZodString>;
138
+ muted: z.ZodOptional<z.ZodString>;
139
+ border: z.ZodOptional<z.ZodString>;
140
+ radius: z.ZodOptional<z.ZodString>;
141
+ fontFamily: z.ZodOptional<z.ZodString>;
142
+ mode: z.ZodDefault<z.ZodEnum<{
143
+ light: "light";
144
+ dark: "dark";
145
+ system: "system";
146
+ }>>;
147
+ }, z.core.$strip>>;
148
+ model: z.ZodPrefault<z.ZodObject<{
149
+ provider: z.ZodDefault<z.ZodString>;
150
+ model: z.ZodDefault<z.ZodString>;
151
+ apiKeyEnv: z.ZodDefault<z.ZodString>;
152
+ baseUrl: z.ZodOptional<z.ZodString>;
153
+ maxTokens: z.ZodDefault<z.ZodNumber>;
154
+ temperature: z.ZodDefault<z.ZodNumber>;
155
+ thinkingLevel: z.ZodDefault<z.ZodEnum<{
156
+ minimal: "minimal";
157
+ low: "low";
158
+ medium: "medium";
159
+ high: "high";
160
+ xhigh: "xhigh";
161
+ max: "max";
162
+ }>>;
163
+ streamReasoning: z.ZodDefault<z.ZodBoolean>;
164
+ }, z.core.$strip>>;
165
+ agent: z.ZodPrefault<z.ZodObject<{
166
+ systemPrompt: z.ZodDefault<z.ZodString>;
167
+ greeting: z.ZodDefault<z.ZodString>;
168
+ suggestedPrompts: z.ZodDefault<z.ZodArray<z.ZodString>>;
169
+ maxTurns: z.ZodDefault<z.ZodNumber>;
170
+ maxBudgetUsd: z.ZodOptional<z.ZodNumber>;
171
+ tools: z.ZodPrefault<z.ZodObject<{
172
+ allow: z.ZodDefault<z.ZodArray<z.ZodString>>;
173
+ deny: z.ZodDefault<z.ZodArray<z.ZodString>>;
174
+ denyByDefault: z.ZodDefault<z.ZodBoolean>;
175
+ }, z.core.$strip>>;
176
+ showToolActivity: z.ZodDefault<z.ZodBoolean>;
177
+ }, z.core.$strip>>;
178
+ auth: z.ZodObject<{
179
+ publishableKey: z.ZodString;
180
+ allowedOrigins: z.ZodDefault<z.ZodArray<z.ZodString>>;
181
+ allowAnonymous: z.ZodDefault<z.ZodBoolean>;
182
+ jwtSecretEnv: z.ZodDefault<z.ZodString>;
183
+ jwksUrl: z.ZodOptional<z.ZodString>;
184
+ jwtIssuer: z.ZodOptional<z.ZodString>;
185
+ jwtAudience: z.ZodOptional<z.ZodString>;
186
+ sessionTtlSeconds: z.ZodDefault<z.ZodNumber>;
187
+ sessionSecretEnv: z.ZodDefault<z.ZodString>;
188
+ }, z.core.$strip>;
189
+ mcpServers: z.ZodDefault<z.ZodArray<z.ZodObject<{
190
+ name: z.ZodString;
191
+ transport: z.ZodDefault<z.ZodEnum<{
192
+ http: "http";
193
+ sse: "sse";
194
+ }>>;
195
+ url: z.ZodString;
196
+ headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
197
+ forwardUserTokenAs: z.ZodOptional<z.ZodString>;
198
+ forwardUserClaims: z.ZodDefault<z.ZodArray<z.ZodString>>;
199
+ }, z.core.$strip>>>;
200
+ apis: z.ZodDefault<z.ZodArray<z.ZodObject<{
201
+ name: z.ZodString;
202
+ spec: z.ZodString;
203
+ baseUrl: z.ZodOptional<z.ZodString>;
204
+ operations: z.ZodDefault<z.ZodArray<z.ZodString>>;
205
+ includePaths: z.ZodDefault<z.ZodArray<z.ZodString>>;
206
+ methods: z.ZodDefault<z.ZodArray<z.ZodEnum<{
207
+ GET: "GET";
208
+ POST: "POST";
209
+ PUT: "PUT";
210
+ PATCH: "PATCH";
211
+ DELETE: "DELETE";
212
+ }>>>;
213
+ headers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodString>>;
214
+ forwardUserTokenAs: z.ZodOptional<z.ZodString>;
215
+ forwardUserClaims: z.ZodDefault<z.ZodArray<z.ZodString>>;
216
+ timeoutMs: z.ZodDefault<z.ZodNumber>;
217
+ maxResponseChars: z.ZodDefault<z.ZodNumber>;
218
+ }, z.core.$strip>>>;
219
+ limits: z.ZodPrefault<z.ZodObject<{
220
+ messagesPerWindow: z.ZodDefault<z.ZodNumber>;
221
+ windowSeconds: z.ZodDefault<z.ZodNumber>;
222
+ sessionsPerIpPerWindow: z.ZodDefault<z.ZodNumber>;
223
+ turnTimeoutMs: z.ZodDefault<z.ZodNumber>;
224
+ }, z.core.$strip>>;
225
+ }, z.core.$strip>;
226
+ type ThinkingLevel = z.infer<typeof thinkingLevelSchema>;
227
+ type WidgetThemeConfig = z.infer<typeof widgetThemeSchema>;
228
+ type ModelConfig = z.infer<typeof modelConfigSchema>;
229
+ type McpServerConfig = z.infer<typeof mcpServerSchema>;
230
+ type ApiSourceConfig = z.infer<typeof apiSourceSchema>;
231
+ type ToolPolicy = z.infer<typeof toolPolicySchema>;
232
+ type AgentConfig = z.infer<typeof agentConfigSchema>;
233
+ type AuthConfig = z.infer<typeof authConfigSchema>;
234
+ type LimitsConfig = z.infer<typeof limitsConfigSchema>;
235
+ type BrandingConfig = z.infer<typeof brandingConfigSchema>;
236
+ type FrankieConfig = z.infer<typeof frankieConfigSchema>;
237
+ type FrankieConfigInput = z.input<typeof frankieConfigSchema>;
238
+ declare function parseFrankieConfig(input: unknown): FrankieConfig;
239
+ /** Helper for `frankie.config.ts` files — gives editors full completion. */
240
+ declare function defineFrankieConfig(config: FrankieConfigInput): FrankieConfigInput;
241
+
242
+ /**
243
+ * The wire protocol between the embedded widget and the Frankie server.
244
+ *
245
+ * Everything the widget renders arrives as one of these events over SSE, so a
246
+ * host that wants to build its own UI only has to implement this union.
247
+ */
248
+ /** A single turn's stop reason, normalised across providers. */
249
+ type StopReason = "end_turn" | "max_tokens" | "max_turns" | "stop_sequence" | "aborted" | "error";
250
+ interface UsageSummary {
251
+ inputTokens: number;
252
+ outputTokens: number;
253
+ /** Present only when the upstream provider reports a price. */
254
+ costUsd?: number;
255
+ }
256
+ /** Server -> client events, streamed as `data: <json>\n\n` over `text/event-stream`. */
257
+ type FrankieServerEvent = {
258
+ type: "session";
259
+ sessionId: string;
260
+ resumed: boolean;
261
+ } | {
262
+ type: "message_start";
263
+ messageId: string;
264
+ } | {
265
+ type: "text_delta";
266
+ text: string;
267
+ } | {
268
+ type: "thinking_delta";
269
+ text: string;
270
+ } | {
271
+ type: "tool_start";
272
+ toolUseId: string;
273
+ name: string;
274
+ label: string;
275
+ input: unknown;
276
+ } | {
277
+ type: "tool_end";
278
+ toolUseId: string;
279
+ ok: boolean;
280
+ preview?: string;
281
+ } | {
282
+ type: "tool_denied";
283
+ toolUseId: string;
284
+ name: string;
285
+ reason: string;
286
+ } | {
287
+ type: "turn_end";
288
+ stopReason: StopReason;
289
+ usage?: UsageSummary;
290
+ } | {
291
+ type: "error";
292
+ code: FrankieErrorCode;
293
+ message: string;
294
+ retryable: boolean;
295
+ } | {
296
+ type: "ping";
297
+ };
298
+ type FrankieErrorCode = "unauthorized" | "forbidden_origin" | "rate_limited" | "session_not_found" | "upstream_error" | "budget_exceeded" | "internal";
299
+ /** Client -> server body for `POST /v1/chat`. */
300
+ interface ChatRequestBody {
301
+ /** Omit to start a new conversation; the server replies with a `session` event. */
302
+ sessionId?: string;
303
+ message: string;
304
+ /**
305
+ * Free-form page context the host passes through (current route, plan tier,
306
+ * feature flags). Surfaced to the agent as a system reminder, never trusted
307
+ * as an instruction.
308
+ */
309
+ context?: Record<string, string | number | boolean | null>;
310
+ }
311
+ /** Client -> server body for `POST /v1/session`. */
312
+ interface CreateSessionBody {
313
+ /**
314
+ * A JWT signed by the host's backend identifying the end user. Required
315
+ * unless the tenant allows anonymous sessions.
316
+ */
317
+ userToken?: string;
318
+ context?: Record<string, string | number | boolean | null>;
319
+ }
320
+ interface CreateSessionResponse {
321
+ /** Short-lived bearer token scoped to this one chat session. */
322
+ sessionToken: string;
323
+ sessionId: string;
324
+ expiresAt: string;
325
+ user: {
326
+ id: string;
327
+ displayName?: string;
328
+ anonymous: boolean;
329
+ };
330
+ }
331
+ /** The subset of tenant config the widget is allowed to see. */
332
+ interface PublicWidgetConfig {
333
+ tenantId: string;
334
+ branding: {
335
+ name: string;
336
+ tagline?: string;
337
+ avatarUrl?: string;
338
+ launcherLabel: string;
339
+ };
340
+ greeting: string;
341
+ suggestedPrompts: string[];
342
+ theme: WidgetTheme;
343
+ /** Whether the widget may open a session without a host-signed user token. */
344
+ allowAnonymous: boolean;
345
+ /** Show tool calls inline as they run. */
346
+ showToolActivity: boolean;
347
+ }
348
+ interface WidgetTheme {
349
+ /** CSS color for primary actions. Any valid CSS color string. */
350
+ primary?: string;
351
+ primaryForeground?: string;
352
+ background?: string;
353
+ foreground?: string;
354
+ muted?: string;
355
+ border?: string;
356
+ /** Border radius in rem, e.g. "0.75". */
357
+ radius?: string;
358
+ fontFamily?: string;
359
+ mode?: "light" | "dark" | "system";
360
+ }
361
+
362
+ interface ToolDecision {
363
+ allowed: boolean;
364
+ reason: string;
365
+ }
366
+ /**
367
+ * Decide whether the agent may run a tool.
368
+ *
369
+ * Patterns are matched exactly, or as a prefix when they end in `*`. MCP tools
370
+ * arrive as `mcp__<server>__<tool>`, so listing `mcp__acme` (no trailing star)
371
+ * also allows every tool on the `acme` server.
372
+ */
373
+ declare function evaluateToolPolicy(toolName: string, policy: ToolPolicy): ToolDecision;
374
+ /** A short human label for a tool call, for the "Frankie is …" line in the UI. */
375
+ declare function describeTool(toolName: string, input: unknown): string;
376
+
377
+ export { type AgentConfig, type ApiSourceConfig, type AuthConfig, type BrandingConfig, type ChatRequestBody, type CreateSessionBody, type CreateSessionResponse, type FrankieConfig, type FrankieConfigInput, type FrankieErrorCode, type FrankieServerEvent, type LimitsConfig, type McpServerConfig, type ModelConfig, type PublicWidgetConfig, type StopReason, type ThinkingLevel, type ToolDecision, type ToolPolicy, type UsageSummary, type WidgetTheme, type WidgetThemeConfig, agentConfigSchema, apiSourceSchema, authConfigSchema, brandingConfigSchema, defineFrankieConfig, describeTool, evaluateToolPolicy, frankieConfigSchema, limitsConfigSchema, mcpServerSchema, modelConfigSchema, parseFrankieConfig, thinkingLevelSchema, toolPolicySchema, widgetThemeSchema };