@flamingo-stack/openframe-frontend-core 0.0.723 → 0.0.725
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-2VOPQJNR.js → chunk-2MMZTACD.js} +2 -2
- package/dist/{chunk-OHC2MPUO.cjs → chunk-2SO3OJFY.cjs} +35 -35
- package/dist/{chunk-YQOJOW2Z.cjs → chunk-2VOZ37BL.cjs} +64 -64
- package/dist/{chunk-WSMOTZRJ.cjs → chunk-4ZZ4TNCY.cjs} +11 -11
- package/dist/{chunk-YUSA7IPD.js → chunk-5FVWDDX6.js} +3 -3
- package/dist/{chunk-PKS2QQJU.js → chunk-6EFNWQRY.js} +2 -1
- package/dist/{chunk-NESUUHPV.cjs → chunk-772242QR.cjs} +76 -76
- package/dist/{chunk-3RIKO2O2.cjs → chunk-7V5KFBY2.cjs} +31 -31
- package/dist/{chunk-MWLVYYRX.cjs → chunk-AI3CLDZO.cjs} +2580 -2120
- package/dist/{chunk-YGIUWQEN.js → chunk-ASHRHL4W.js} +7 -7
- package/dist/{chunk-A7JPMNHF.js → chunk-ASIXPRHV.js} +6 -6
- package/dist/{chunk-7JXCLUU7.js → chunk-AX4F35C2.js} +2 -2
- package/dist/{chunk-TDSLKKX7.cjs → chunk-B7234BE2.cjs} +16 -16
- package/dist/{chunk-SBCJFJ6Q.js → chunk-F56GNKX2.js} +4 -4
- package/dist/{chunk-VIFVSFYY.js → chunk-F77J34W2.js} +1 -1
- package/dist/{chunk-JENNI7XU.cjs → chunk-HEQ4GPYE.cjs} +5 -4
- package/dist/{chunk-LV6UJD2K.cjs → chunk-IITB5TJR.cjs} +10 -2
- package/dist/{chunk-WVA7SCLY.js → chunk-IOTAUWWF.js} +1 -1
- package/dist/{chunk-OVG6MV3X.js → chunk-JAKG6BY7.js} +6 -6
- package/dist/{chunk-F6JAGSKV.js → chunk-JVHP7Y4S.js} +5 -5
- package/dist/{chunk-WY4SLTMZ.js → chunk-JXJFUGJY.js} +1 -1
- package/dist/{chunk-GYUFKNOQ.cjs → chunk-KLCOSY7B.cjs} +4 -4
- package/dist/{chunk-P7MDECYI.cjs → chunk-KNLRL63O.cjs} +41 -41
- package/dist/{chunk-VGXAZEQP.cjs → chunk-LR6DJY4Z.cjs} +17 -17
- package/dist/{chunk-KSADTFNZ.cjs → chunk-LYQYLPPV.cjs} +32 -32
- package/dist/{chunk-QBXEF7D5.js → chunk-MGTZ2BKY.js} +4 -4
- package/dist/{chunk-IIBTYCEN.js → chunk-MLFS5G3V.js} +89 -14
- package/dist/{chunk-GRDJR2Q7.js → chunk-MSPXMSMY.js} +1 -1
- package/dist/{chunk-FDWYBJYD.cjs → chunk-NJV3LIDE.cjs} +3 -3
- package/dist/{chunk-JL7AHSFE.js → chunk-OBMWSUBK.js} +6 -6
- package/dist/{chunk-N4VCU6XP.js → chunk-PUADVXJD.js} +1 -1
- package/dist/{chunk-KY4WQYYG.cjs → chunk-QV4GO3GW.cjs} +19 -19
- package/dist/{chunk-OWRD2GZU.cjs → chunk-RU6BTELI.cjs} +687 -612
- package/dist/{chunk-Y5H3M7OM.cjs → chunk-SE4O4HCD.cjs} +23 -23
- package/dist/{chunk-2MC4DRSC.cjs → chunk-SEVKFMKR.cjs} +3 -3
- package/dist/{chunk-UYMTAFHG.js → chunk-TU5LEF6A.js} +1 -1
- package/dist/{chunk-NFABAOMD.cjs → chunk-U6LRRG2E.cjs} +15 -15
- package/dist/{chunk-G6YNPBWV.js → chunk-W2DXHR2R.js} +3045 -2585
- package/dist/{chunk-KSZRALRL.cjs → chunk-YPEILGVZ.cjs} +3 -3
- package/dist/{chunk-EWED6ISQ.js → chunk-YQDKVGKO.js} +9 -1
- package/dist/{chunk-6QTGLBJH.cjs → chunk-ZSXZE4FJ.cjs} +3 -3
- package/dist/{chunk-XTG7W75B.js → chunk-ZZRUKEN2.js} +4 -4
- package/dist/{cloud-tenants-3TVX7U23.cjs → cloud-tenants-SMULXU54.cjs} +7 -7
- package/dist/{cloud-tenants-N6KV2T7X.js → cloud-tenants-US63E2HV.js} +6 -6
- package/dist/components/case-studies/index.cjs +20 -20
- package/dist/components/case-studies/index.js +7 -7
- package/dist/components/chat/entity-cards/dispatch.d.ts.map +1 -1
- package/dist/components/chat/index.cjs +5 -5
- package/dist/components/chat/index.js +4 -4
- package/dist/components/chat/utils/icon-library.d.ts +2 -0
- package/dist/components/chat/utils/icon-library.d.ts.map +1 -1
- package/dist/components/contact/index.cjs +8 -8
- package/dist/components/contact/index.js +7 -7
- package/dist/components/docs/index.cjs +11 -11
- package/dist/components/docs/index.js +10 -10
- package/dist/components/embeds/index.cjs +8 -8
- package/dist/components/embeds/index.js +7 -7
- package/dist/components/faq/index.cjs +8 -8
- package/dist/components/faq/index.js +7 -7
- package/dist/components/features/index.cjs +23 -7
- package/dist/components/features/index.d.ts +1 -0
- package/dist/components/features/index.d.ts.map +1 -1
- package/dist/components/features/index.js +22 -6
- package/dist/components/features/model-token-rates.d.ts +179 -0
- package/dist/components/features/model-token-rates.d.ts.map +1 -0
- package/dist/components/help-center-pages/index.cjs +106 -106
- package/dist/components/help-center-pages/index.js +18 -18
- package/dist/components/index.cjs +71 -55
- package/dist/components/index.js +34 -18
- package/dist/components/meeting-scheduler/index.cjs +32 -32
- package/dist/components/meeting-scheduler/index.js +6 -6
- package/dist/components/navigation/index.cjs +10 -10
- package/dist/components/navigation/index.js +9 -9
- package/dist/components/onboarding-guides/index.cjs +10 -10
- package/dist/components/onboarding-guides/index.js +9 -9
- package/dist/components/product-demo/index.cjs +7 -7
- package/dist/components/product-demo/index.js +7 -7
- package/dist/components/related-content/index.cjs +4 -4
- package/dist/components/related-content/index.js +3 -3
- package/dist/components/tickets/index.cjs +11 -11
- package/dist/components/tickets/index.js +10 -10
- package/dist/components/ui/index.cjs +7 -7
- package/dist/components/ui/index.js +6 -6
- package/dist/{devices-MAALZ7DX.cjs → devices-6ZURNFRB.cjs} +8 -8
- package/dist/{devices-275UZZUS.js → devices-JWHGWKLK.js} +6 -6
- package/dist/index.cjs +45 -11
- package/dist/index.js +44 -10
- package/dist/{knowledge-YMMULPPK.cjs → knowledge-CY66JZ54.cjs} +8 -8
- package/dist/{knowledge-THXC2KC3.js → knowledge-TEDPLCFX.js} +6 -6
- package/dist/{logs-IBUKQOHS.cjs → logs-MO357RE7.cjs} +15 -15
- package/dist/{logs-GM2XBHYT.js → logs-S46THPPD.js} +6 -6
- package/dist/{policies-NKMRK6RR.js → policies-BUXT7DKF.js} +6 -6
- package/dist/{policies-J5GJXD6G.cjs → policies-GSH4K5YP.cjs} +11 -11
- package/dist/{remote-session-Z2YCUPHU.cjs → remote-session-CSX6ESSG.cjs} +5 -5
- package/dist/{remote-session-WCLR47RN.js → remote-session-ZBCWD5A5.js} +3 -3
- package/dist/{software-update-JHC4T4SE.cjs → software-update-2ETT35NM.cjs} +11 -11
- package/dist/{software-update-EKKMKDWI.js → software-update-YKS6KLX2.js} +6 -6
- package/dist/utils/ai-providers.d.ts +29 -0
- package/dist/utils/ai-providers.d.ts.map +1 -0
- package/dist/utils/index.cjs +76 -2
- package/dist/utils/index.d.ts +2 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +68 -3
- package/dist/utils/list-url.d.ts.map +1 -1
- package/dist/utils/model-token-rates.d.ts +55 -0
- package/dist/utils/model-token-rates.d.ts.map +1 -0
- package/dist/utils/source-icons.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/chat/entity-cards/dispatch.tsx +3 -0
- package/src/components/chat/utils/icon-library.tsx +14 -3
- package/src/components/chat/utils/source-row-cta.ts +3 -3
- package/src/components/features/index.ts +1 -0
- package/src/components/features/model-token-rates.tsx +696 -0
- package/src/utils/ai-providers.ts +46 -0
- package/src/utils/index.ts +2 -0
- package/src/utils/list-url.ts +1 -0
- package/src/utils/model-token-rates.ts +103 -0
- package/src/utils/source-icons.ts +3 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The AI model providers the product names: what each is called and the NAME of
|
|
3
|
+
* its mark in the icon set. THE one owner of both, for every surface that shows
|
|
4
|
+
* a provider (the token rates, a model picker). Server-safe: it holds names
|
|
5
|
+
* only, and the mark is resolved from the icon set by that name where it is
|
|
6
|
+
* drawn (`findIcon`), so no surface imports a provider's icon.
|
|
7
|
+
*
|
|
8
|
+
* A host that is told a provider's name or mark by its server states them on
|
|
9
|
+
* the record and they win. A provider this list has not met is named from its
|
|
10
|
+
* key, and its mark is looked up by the icon set's own naming
|
|
11
|
+
* (`<provider>-logo-grey`), so a logo added to the set shows with no change here.
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
export interface AiProvider {
|
|
15
|
+
/** The name people know the provider by. */
|
|
16
|
+
label: string;
|
|
17
|
+
/** The icon set's name of the provider's monochrome mark. */
|
|
18
|
+
icon: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** Keyed by the provider key billing sends (`ANTHROPIC`). */
|
|
22
|
+
export const AI_PROVIDERS: Readonly<Record<string, AiProvider>> = {
|
|
23
|
+
ANTHROPIC: { label: 'Anthropic', icon: 'anthropic-logo-grey' },
|
|
24
|
+
OPENAI: { label: 'OpenAI', icon: 'openai-logo-grey' },
|
|
25
|
+
GOOGLE_GEMINI: { label: 'Google Gemini', icon: 'gemini-logo-grey' },
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const words = (key: string): string[] =>
|
|
29
|
+
key
|
|
30
|
+
.toLowerCase()
|
|
31
|
+
.split(/[^a-z0-9]+/)
|
|
32
|
+
.filter(Boolean);
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* A provider by its key: what a host stated for it, else this list's entry,
|
|
36
|
+
* else its key read as a name and the mark the icon set would hold for it.
|
|
37
|
+
*/
|
|
38
|
+
export function aiProvider(key: string, stated?: { label?: string | null; icon?: string | null } | null): AiProvider {
|
|
39
|
+
const known = AI_PROVIDERS[key];
|
|
40
|
+
const parts = words(key);
|
|
41
|
+
return {
|
|
42
|
+
label:
|
|
43
|
+
stated?.label || known?.label || parts.map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ') || key,
|
|
44
|
+
icon: stated?.icon || known?.icon || `${parts.join('-')}-logo-grey`,
|
|
45
|
+
};
|
|
46
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -17,6 +17,8 @@ export {
|
|
|
17
17
|
// source of truth). Re-exported here so existing callers that pull from
|
|
18
18
|
// the barrel keep working without changing imports.
|
|
19
19
|
export { formatDate, formatNumber, formatPrice, formatBytes, formatUrlForDisplay } from './format';
|
|
20
|
+
export * from './ai-providers';
|
|
21
|
+
export * from './model-token-rates';
|
|
20
22
|
export { TRIAL_DAYS, TRIAL_LABELS } from './trial';
|
|
21
23
|
export {
|
|
22
24
|
VENDOR_CLASSIFICATIONS,
|
package/src/utils/list-url.ts
CHANGED
|
@@ -118,6 +118,7 @@ const BUILDERS: Record<string, (ids: string[], base: string) => string> = {
|
|
|
118
118
|
prospect_call: (ids, b) => `${b}/api/prospect-calls?ids=${ids.join(',')}`,
|
|
119
119
|
// The public website's own pages (live source; ChatRef-shaped items like the objects above).
|
|
120
120
|
site_page: (ids, b) => `${b}/api/site-pages?ids=${ids.join(',')}`,
|
|
121
|
+
openframe_price: (ids, b) => `${b}/api/openframe-pricing?ids=${ids.join(',')}`,
|
|
121
122
|
// The OpenMSP vendor directory (indexed source).
|
|
122
123
|
vendor: (ids, b) => `${b}/api/vendors/cards?ids=${ids.join(',')}`,
|
|
123
124
|
// Code intelligence — per-object card hydration, same `handleEntityCardList`
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The per-model AI token exchange rates: their shape and how a rate is written.
|
|
3
|
+
* Server-safe (no client code), so a host's server (a chat source, a page's
|
|
4
|
+
* metadata) states a rate exactly as the shared table (`ModelTokenRates`) does.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { aiProvider } from './ai-providers';
|
|
8
|
+
|
|
9
|
+
/** One model's rates: OpenFrame tokens charged per ONE token of the model. */
|
|
10
|
+
export interface ModelTokenRate {
|
|
11
|
+
modelName: string;
|
|
12
|
+
/** The name people know the model by; the model's id stands in when it is missing. */
|
|
13
|
+
displayName?: string | null;
|
|
14
|
+
/** The provider's key (`ANTHROPIC`, `OPENAI`, `GOOGLE_GEMINI`); an unknown one is shown by name, without a mark. */
|
|
15
|
+
providerType: string;
|
|
16
|
+
/** The provider's name, when the host's server states one; else the shared provider list names it. */
|
|
17
|
+
providerLabel?: string | null;
|
|
18
|
+
/** The icon set's name of the provider's mark, when the host's server states one; else the shared provider list's. */
|
|
19
|
+
providerIcon?: string | null;
|
|
20
|
+
inputTokenRate: number;
|
|
21
|
+
outputTokenRate: number;
|
|
22
|
+
/** Charged for an input token read back from the prompt cache. Shown only where the table has room for it. */
|
|
23
|
+
cacheReadInputTokenRate?: number | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** What a figure that cannot be stated is written as. */
|
|
27
|
+
export const TOKEN_RATE_EMPTY = '\u2014';
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* A rate as a multiplier. Two decimals from 0.1 up ("1.33×", "5×"), two
|
|
31
|
+
* significant digits under it ("0.033×"), so a cheap model's rate is never
|
|
32
|
+
* rounded to nothing.
|
|
33
|
+
*/
|
|
34
|
+
export function formatTokenRate(value: number | null | undefined): string {
|
|
35
|
+
if (value == null || !Number.isFinite(value) || value <= 0) return TOKEN_RATE_EMPTY;
|
|
36
|
+
const rounded = value >= 0.1 ? Number(value.toFixed(2)) : Number(value.toPrecision(2));
|
|
37
|
+
return `${rounded}\u00d7`;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** What OpenFrame tokens cost: `price` USD buys `tokens` of them. */
|
|
41
|
+
export interface TokenPrice {
|
|
42
|
+
tokens: number;
|
|
43
|
+
price: number;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** What a number of OpenFrame tokens costs in USD at a price. Null without a price. */
|
|
47
|
+
export function tokenCost(tokens: number, tokenPrice: TokenPrice | null | undefined): number | null {
|
|
48
|
+
if (!tokenPrice || !(tokenPrice.tokens > 0) || !(tokenPrice.price > 0) || !(tokens >= 0)) return null;
|
|
49
|
+
return (tokens / tokenPrice.tokens) * tokenPrice.price;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/** The units a token count is shortened to, largest first. */
|
|
53
|
+
const TOKEN_AMOUNT_UNITS = [
|
|
54
|
+
{ size: 1_000_000_000, suffix: 'B' },
|
|
55
|
+
{ size: 1_000_000, suffix: 'M' },
|
|
56
|
+
{ size: 1_000, suffix: 'K' },
|
|
57
|
+
] as const;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A token count in short form: "850", "10K", "750K", "1.25M". The unit is chosen
|
|
61
|
+
* from the ROUNDED figure, so a count just under a unit reads as the next one
|
|
62
|
+
* ("1M", never "1000K").
|
|
63
|
+
*/
|
|
64
|
+
export function formatTokenAmount(tokens: number | null | undefined): string {
|
|
65
|
+
if (tokens == null || !Number.isFinite(tokens) || tokens < 0) return TOKEN_RATE_EMPTY;
|
|
66
|
+
const whole = Math.round(tokens);
|
|
67
|
+
if (whole < 1_000) return String(whole);
|
|
68
|
+
for (const [index, unit] of TOKEN_AMOUNT_UNITS.entries()) {
|
|
69
|
+
if (whole < unit.size) continue;
|
|
70
|
+
const figure = Number((whole / unit.size).toPrecision(3));
|
|
71
|
+
// Rounded up to a thousand of this unit: it is one of the unit above.
|
|
72
|
+
const larger = TOKEN_AMOUNT_UNITS[index - 1];
|
|
73
|
+
return figure >= 1_000 && larger ? `1${larger.suffix}` : `${figure}${unit.suffix}`;
|
|
74
|
+
}
|
|
75
|
+
return String(whole);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* How many of a model's tokens a balance of OpenFrame tokens runs at a rate:
|
|
80
|
+
* the balance divided by the rate. Null without a rate.
|
|
81
|
+
*/
|
|
82
|
+
export function tokensForBalance(balance: number, rate: number | null | undefined): number | null {
|
|
83
|
+
if (rate == null || !Number.isFinite(rate) || rate <= 0 || !(balance > 0)) return null;
|
|
84
|
+
return balance / rate;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** A provider's name: what the host stated for it, else the shared provider list's (`aiProvider`). */
|
|
88
|
+
export function tokenRateProviderLabel(providerType: string, stated?: string | null): string {
|
|
89
|
+
return aiProvider(providerType, { label: stated }).label;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/** The rates under their providers, in the order the host gave them (providers by first appearance). */
|
|
93
|
+
export function groupTokenRatesByProvider<T extends ModelTokenRate>(
|
|
94
|
+
rates: readonly T[],
|
|
95
|
+
): { providerType: string; rates: T[] }[] {
|
|
96
|
+
const groups = new Map<string, T[]>();
|
|
97
|
+
for (const rate of rates) {
|
|
98
|
+
const group = groups.get(rate.providerType);
|
|
99
|
+
if (group) group.push(rate);
|
|
100
|
+
else groups.set(rate.providerType, [rate]);
|
|
101
|
+
}
|
|
102
|
+
return [...groups].map(([providerType, grouped]) => ({ providerType, rates: grouped }));
|
|
103
|
+
}
|
|
@@ -58,6 +58,7 @@ export const SOURCE_ICON_NAMES: Record<string, string> = {
|
|
|
58
58
|
'trust-center': 'shield-check',
|
|
59
59
|
// The public website's own pages (live source): the site's own mark, as a glyph in the slot's colour
|
|
60
60
|
'website-pages': 'flamingo-logo-grey',
|
|
61
|
+
'openframe-pricing': 'money-bill-dollar',
|
|
61
62
|
// The OpenMSP vendor directory: the icon the site menu's "Tool directory" entry draws (it reads this one)
|
|
62
63
|
vendors: 'package-search',
|
|
63
64
|
|
|
@@ -150,6 +151,7 @@ export const SOURCE_LABELS_BY_TABLE: Record<string, string> = {
|
|
|
150
151
|
// Trust
|
|
151
152
|
'trust-center': 'Trust Center',
|
|
152
153
|
'website-pages': 'Website',
|
|
154
|
+
'openframe-pricing': 'OpenFrame pricing',
|
|
153
155
|
vendors: 'Vendor Directory',
|
|
154
156
|
|
|
155
157
|
// Financials
|
|
@@ -255,6 +257,7 @@ export const DEFAULT_DOCUMENT_TYPE_TO_TABLE_ID: Record<string, string> = {
|
|
|
255
257
|
// Trust
|
|
256
258
|
trust_center: 'trust-center',
|
|
257
259
|
site_page: 'website-pages',
|
|
260
|
+
openframe_price: 'openframe-pricing',
|
|
258
261
|
vendor: 'vendors',
|
|
259
262
|
|
|
260
263
|
// Financials
|