@aglyn/plugins-ai 1.0.0-beta.225 → 1.0.0-beta.227
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/README.md +2 -1
- package/package.json +17 -17
- package/src/lib/billing/ai-month-meter.js +5 -3
- package/src/lib/billing/ai-month-meter.js.map +1 -1
- package/src/lib/billing/ai-overage-ledger.js +3 -1
- package/src/lib/billing/ai-overage-ledger.js.map +1 -1
- package/src/lib/components/ai-brief-dialog.component.d.ts +6 -2
- package/src/lib/components/ai-brief-dialog.component.js +35 -17
- package/src/lib/components/ai-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-describe-automation.component.js +17 -2
- package/src/lib/components/ai-describe-automation.component.js.map +1 -1
- package/src/lib/components/ai-insight-dialog.component.js +24 -2
- package/src/lib/components/ai-insight-dialog.component.js.map +1 -1
- package/src/lib/components/ai-job-events.d.ts +14 -0
- package/src/lib/components/ai-job-events.js +76 -0
- package/src/lib/components/ai-job-events.js.map +1 -0
- package/src/lib/components/ai-job-follow.component.d.ts +49 -0
- package/src/lib/components/ai-job-follow.component.js +210 -0
- package/src/lib/components/ai-job-follow.component.js.map +1 -0
- package/src/lib/components/ai-job-links.d.ts +42 -0
- package/src/lib/components/ai-job-links.js +140 -0
- package/src/lib/components/ai-job-links.js.map +1 -0
- package/src/lib/components/ai-job-plan.component.d.ts +13 -6
- package/src/lib/components/ai-job-plan.component.js +29 -3
- package/src/lib/components/ai-job-plan.component.js.map +1 -1
- package/src/lib/components/ai-job-requests.d.ts +24 -0
- package/src/lib/components/ai-job-requests.js +76 -0
- package/src/lib/components/ai-job-requests.js.map +1 -0
- package/src/lib/components/ai-jobs-indicator.component.d.ts +25 -0
- package/src/lib/components/ai-jobs-indicator.component.js +80 -0
- package/src/lib/components/ai-jobs-indicator.component.js.map +1 -0
- package/src/lib/components/ai-jobs-store.d.ts +81 -0
- package/src/lib/components/ai-jobs-store.js +218 -0
- package/src/lib/components/ai-jobs-store.js.map +1 -0
- package/src/lib/components/ai-page-brief-dialog.component.d.ts +3 -3
- package/src/lib/components/ai-page-brief-dialog.component.js.map +1 -1
- package/src/lib/components/ai-site-build-page.component.d.ts +23 -0
- package/src/lib/components/ai-site-build-page.component.js +377 -0
- package/src/lib/components/ai-site-build-page.component.js.map +1 -0
- package/src/lib/components/ai-site-start-card.component.d.ts +1 -1
- package/src/lib/components/ai-site-start-card.component.js +522 -130
- package/src/lib/components/ai-site-start-card.component.js.map +1 -1
- package/src/lib/components/ai-site-starter-fallback.component.d.ts +24 -0
- package/src/lib/components/ai-site-starter-fallback.component.js +112 -0
- package/src/lib/components/ai-site-starter-fallback.component.js.map +1 -0
- package/src/lib/components/assist-jobs-drawer.component.d.ts +18 -20
- package/src/lib/components/assist-jobs-drawer.component.js +152 -172
- package/src/lib/components/assist-jobs-drawer.component.js.map +1 -1
- package/src/lib/components/assist-panel.component.js +62 -6
- package/src/lib/components/assist-panel.component.js.map +1 -1
- package/src/lib/components/staff-ai-credit-return.component.d.ts +55 -0
- package/src/lib/components/staff-ai-credit-return.component.js +346 -0
- package/src/lib/components/staff-ai-credit-return.component.js.map +1 -0
- package/src/lib/components/staff-org-ai-card.component.js +364 -279
- package/src/lib/components/staff-org-ai-card.component.js.map +1 -1
- package/src/lib/components/staff-user-ai-usage-card.component.d.ts +4 -0
- package/src/lib/components/staff-user-ai-usage-card.component.js +83 -28
- package/src/lib/components/staff-user-ai-usage-card.component.js.map +1 -1
- package/src/lib/components/use-ai-job-run.js +5 -18
- package/src/lib/components/use-ai-job-run.js.map +1 -1
- package/src/lib/jobs/ai-job-auto-confirm.d.ts +52 -0
- package/src/lib/jobs/ai-job-auto-confirm.js +62 -0
- package/src/lib/jobs/ai-job-auto-confirm.js.map +1 -0
- package/src/lib/jobs/ai-job-plan-step.d.ts +33 -2
- package/src/lib/jobs/ai-job-plan-step.js +161 -17
- package/src/lib/jobs/ai-job-plan-step.js.map +1 -1
- package/src/lib/jobs/ai-job-site-step.d.ts +7 -0
- package/src/lib/jobs/ai-job-site-step.js +34 -4
- package/src/lib/jobs/ai-job-site-step.js.map +1 -1
- package/src/lib/jobs/ai-job-text-step.d.ts +7 -0
- package/src/lib/jobs/ai-job-text-step.js.map +1 -1
- package/src/lib/jobs/ai-jobs-notify.d.ts +37 -0
- package/src/lib/jobs/ai-jobs-notify.js +51 -0
- package/src/lib/jobs/ai-jobs-notify.js.map +1 -0
- package/src/lib/jobs/ai-jobs.d.ts +31 -4
- package/src/lib/jobs/ai-jobs.js +196 -32
- package/src/lib/jobs/ai-jobs.js.map +1 -1
- package/src/lib/model/ai-job-activity.d.ts +112 -0
- package/src/lib/model/ai-job-activity.js +144 -0
- package/src/lib/model/ai-job-activity.js.map +1 -0
- package/src/lib/model/ai-job-failure-copy.d.ts +69 -0
- package/src/lib/model/ai-job-failure-copy.js +78 -0
- package/src/lib/model/ai-job-failure-copy.js.map +1 -0
- package/src/lib/model/ai-job-notice.d.ts +61 -0
- package/src/lib/model/ai-job-notice.js +112 -0
- package/src/lib/model/ai-job-notice.js.map +1 -0
- package/src/lib/model/ai-jobs.types.d.ts +26 -0
- package/src/lib/model/ai-jobs.types.js +1 -0
- package/src/lib/model/ai-jobs.types.js.map +1 -1
- package/src/lib/model/ai-plan-capabilities.d.ts +7 -0
- package/src/lib/model/ai-plan-capabilities.js.map +1 -1
- package/src/lib/model/ai-site-build-progress.d.ts +45 -0
- package/src/lib/model/ai-site-build-progress.js +76 -0
- package/src/lib/model/ai-site-build-progress.js.map +1 -0
- package/src/lib/model/ai-site-inventory.d.ts +9 -0
- package/src/lib/model/ai-site-inventory.js +7 -2
- package/src/lib/model/ai-site-inventory.js.map +1 -1
- package/src/lib/model/ai-site-job.d.ts +93 -2
- package/src/lib/model/ai-site-job.js +88 -7
- package/src/lib/model/ai-site-job.js.map +1 -1
- package/src/lib/model/ai-site-start.d.ts +3 -1
- package/src/lib/model/ai-site-start.js +6 -4
- package/src/lib/model/ai-site-start.js.map +1 -1
- package/src/lib/model/ai-template-subjects.d.ts +4 -3
- package/src/lib/model/ai-template-subjects.js +5 -4
- package/src/lib/model/ai-template-subjects.js.map +1 -1
- package/src/lib/plan-entitlements.d.ts +3 -3
- package/src/lib/plan-entitlements.js +3 -3
- package/src/lib/plan-entitlements.js.map +1 -1
- package/src/lib/plugin.js +28 -0
- package/src/lib/plugin.js.map +1 -1
- package/src/lib/runtime/ai-abuse-guards.d.ts +9 -6
- package/src/lib/runtime/ai-abuse-guards.js +10 -7
- package/src/lib/runtime/ai-abuse-guards.js.map +1 -1
- package/src/lib/runtime/ai-doctrine-validators.js +31 -4
- package/src/lib/runtime/ai-doctrine-validators.js.map +1 -1
- package/src/lib/runtime/ai-gate.d.ts +3 -2
- package/src/lib/runtime/ai-gate.js +3 -2
- package/src/lib/runtime/ai-gate.js.map +1 -1
- package/src/lib/runtime/ai-palette.generated.js +12 -4
- package/src/lib/runtime/ai-palette.generated.js.map +1 -1
- package/src/lib/runtime/site-inventory.d.ts +16 -1
- package/src/lib/runtime/site-inventory.js +43 -3
- package/src/lib/runtime/site-inventory.js.map +1 -1
- package/src/lib/server/ai-admin-credits.d.ts +21 -0
- package/src/lib/server/ai-admin-credits.js +213 -0
- package/src/lib/server/ai-admin-credits.js.map +1 -0
- package/src/lib/server/ai-admin-org.js +12 -5
- package/src/lib/server/ai-admin-org.js.map +1 -1
- package/src/lib/server/ai-admin-signals.js +3 -1
- package/src/lib/server/ai-admin-signals.js.map +1 -1
- package/src/lib/server/ai-admin-user.js +12 -1
- package/src/lib/server/ai-admin-user.js.map +1 -1
- package/src/lib/server/ai-allotments.js +3 -2
- package/src/lib/server/ai-allotments.js.map +1 -1
- package/src/lib/server/ai-jobs-route.js +20 -2
- package/src/lib/server/ai-jobs-route.js.map +1 -1
- package/src/lib/server/assist-chat.js +3 -2
- package/src/lib/server/assist-chat.js.map +1 -1
- package/src/lib/server/billing-credits.js +4 -3
- package/src/lib/server/billing-credits.js.map +1 -1
- package/src/lib/server/billing-overage.js +3 -2
- package/src/lib/server/billing-overage.js.map +1 -1
- package/src/lib/server.js +11 -0
- package/src/lib/server.js.map +1 -1
- package/src/lib/usage/assist-credit-returns-write.d.ts +75 -0
- package/src/lib/usage/assist-credit-returns-write.js +150 -0
- package/src/lib/usage/assist-credit-returns-write.js.map +1 -0
- package/src/lib/usage/assist-credit-returns.d.ts +68 -0
- package/src/lib/usage/assist-credit-returns.js +79 -0
- package/src/lib/usage/assist-credit-returns.js.map +1 -0
- package/src/lib/usage/assist-free-taste.js +6 -3
- package/src/lib/usage/assist-free-taste.js.map +1 -1
- package/src/lib/usage/assist-job-refund.d.ts +100 -0
- package/src/lib/usage/assist-job-refund.js +109 -0
- package/src/lib/usage/assist-job-refund.js.map +1 -0
- package/src/lib/usage/assist-usage.js +5 -2
- package/src/lib/usage/assist-usage.js.map +1 -1
- package/src/lib/usage/staff-org-ai.d.ts +31 -1
- package/src/lib/usage/staff-org-ai.js +19 -2
- package/src/lib/usage/staff-org-ai.js.map +1 -1
|
@@ -27,7 +27,8 @@ import { useUser } from "@aglyn/tenant-feature-instance";
|
|
|
27
27
|
import { authorizedFetch } from "@aglyn/shared-util-http/authorized-token";
|
|
28
28
|
import { Alert, Chip, Stack, TableBody, TableCell, TableHead, TableRow, Typography } from "@mui/material";
|
|
29
29
|
import { useRouter } from "next/navigation";
|
|
30
|
-
import { useEffect, useMemo, useRef, useState } from "react";
|
|
30
|
+
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
31
|
+
import { StaffCreditReturnActions, StaffCreditReturnDialog } from "./staff-ai-credit-return.component.js";
|
|
31
32
|
/**
|
|
32
33
|
* THE STAFF AI CARD (AGL-2930): everything about one org's AI usage on the
|
|
33
34
|
* page staff already open to look at that org.
|
|
@@ -52,6 +53,11 @@ import { useEffect, useMemo, useRef, useState } from "react";
|
|
|
52
53
|
* sends and generates, and how much of its prompt the cache served.
|
|
53
54
|
* - **Margin** — spend against what AI brings in, red when it is over.
|
|
54
55
|
* - **Actions** — where the override editor and the AI pause live.
|
|
56
|
+
*
|
|
57
|
+
* The header carries the card's two acts (AGL-3595): give credits back to
|
|
58
|
+
* the band (and, on a Free workspace, to the owner's allowance), or reset
|
|
59
|
+
* the month — and each recent job offers the same give-back, prefilled with
|
|
60
|
+
* that job's spend.
|
|
55
61
|
*/ const credits = (value)=>value == null ? '—' : Math.round(value).toLocaleString();
|
|
56
62
|
/**
|
|
57
63
|
* Four decimals under a dollar, two above (the assist-signals page's rule):
|
|
@@ -131,7 +137,10 @@ function RefusalsRow({ refusals }) {
|
|
|
131
137
|
})
|
|
132
138
|
});
|
|
133
139
|
}
|
|
134
|
-
function JobsSection({ jobs }) {
|
|
140
|
+
function JobsSection({ jobs, onGiveBack }) {
|
|
141
|
+
const columns = useMemo(()=>jobColumns(onGiveBack), [
|
|
142
|
+
onGiveBack
|
|
143
|
+
]);
|
|
135
144
|
if (jobs === null) {
|
|
136
145
|
return /*#__PURE__*/ _jsx(Alert, {
|
|
137
146
|
severity: "warning",
|
|
@@ -182,7 +191,7 @@ function JobsSection({ jobs }) {
|
|
|
182
191
|
}) : null,
|
|
183
192
|
/*#__PURE__*/ _jsx(ListTable, {
|
|
184
193
|
rows: jobs.recent,
|
|
185
|
-
columns:
|
|
194
|
+
columns: columns,
|
|
186
195
|
getRowId: (job)=>job.id,
|
|
187
196
|
rowHeight: TABLE_ROW_HEIGHT,
|
|
188
197
|
noRowsLabel: "No recent jobs",
|
|
@@ -198,69 +207,81 @@ function JobsSection({ jobs }) {
|
|
|
198
207
|
* The recent jobs, one column per fact. Who started a job is a column of
|
|
199
208
|
* its own rather than a link tucked beside the date, so it sorts like the
|
|
200
209
|
* rest; the credits sort by what was SPENT, which is the figure the
|
|
201
|
-
* pool was charged.
|
|
202
|
-
*/ const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
210
|
+
* pool was charged. The row's action gives that spend back (AGL-3595).
|
|
211
|
+
*/ const jobColumns = (onGiveBack)=>[
|
|
212
|
+
{
|
|
213
|
+
field: 'id',
|
|
214
|
+
headerName: 'Job',
|
|
215
|
+
flex: 1,
|
|
216
|
+
minWidth: 200,
|
|
217
|
+
renderCell: ({ row })=>/*#__PURE__*/ _jsx(Typography, {
|
|
218
|
+
variant: "body2",
|
|
219
|
+
noWrap: true,
|
|
220
|
+
title: row.id,
|
|
221
|
+
sx: {
|
|
222
|
+
fontFamily: 'monospace'
|
|
223
|
+
},
|
|
224
|
+
children: row.id
|
|
225
|
+
})
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
field: 'kind',
|
|
229
|
+
headerName: 'Kind',
|
|
230
|
+
width: 120,
|
|
231
|
+
valueFormatter: (value)=>value || '—'
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
field: 'status',
|
|
235
|
+
headerName: 'Status',
|
|
236
|
+
width: 130,
|
|
237
|
+
valueFormatter: (value)=>String(value != null ? value : '').replace('_', ' ')
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
field: 'creditsSpent',
|
|
241
|
+
headerName: 'Credits',
|
|
242
|
+
type: 'number',
|
|
243
|
+
align: 'right',
|
|
244
|
+
headerAlign: 'right',
|
|
245
|
+
width: 140,
|
|
246
|
+
valueFormatter: (value, row)=>`${credits(value)} / ${credits(row.creditsReserved)}`
|
|
247
|
+
},
|
|
248
|
+
{
|
|
249
|
+
field: 'createdAt',
|
|
250
|
+
headerName: 'Started',
|
|
251
|
+
width: 120,
|
|
252
|
+
valueFormatter: (value)=>when(value)
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
field: 'createdBy',
|
|
256
|
+
headerName: 'Started by',
|
|
257
|
+
flex: 1,
|
|
258
|
+
minWidth: 240,
|
|
259
|
+
renderCell: ({ row })=>row.createdBy ? /*#__PURE__*/ _jsx(AppLink, {
|
|
260
|
+
href: buildRoute(Route.ADMIN_USER_DETAIL, {
|
|
261
|
+
uid: row.createdBy
|
|
262
|
+
}),
|
|
263
|
+
variant: "body2",
|
|
264
|
+
underline: "hover",
|
|
265
|
+
noWrap: true,
|
|
266
|
+
sx: {
|
|
267
|
+
fontFamily: 'monospace'
|
|
268
|
+
},
|
|
269
|
+
children: row.createdBy
|
|
270
|
+
}) : '—'
|
|
271
|
+
},
|
|
272
|
+
listActionsColumn((row)=>/*#__PURE__*/ _jsx(ListRowActions, {
|
|
273
|
+
label: row.id,
|
|
274
|
+
items: [
|
|
275
|
+
{
|
|
276
|
+
key: 'give-back',
|
|
277
|
+
label: 'Give back this job’s credits',
|
|
278
|
+
disabled: row.creditsSpent <= 0,
|
|
279
|
+
disabledReason: row.creditsSpent <= 0 ? 'This job spent no credits.' : undefined,
|
|
280
|
+
onClick: ()=>onGiveBack(row)
|
|
281
|
+
}
|
|
282
|
+
]
|
|
283
|
+
}))
|
|
284
|
+
];
|
|
264
285
|
const tokenCount = (value)=>Math.round(value).toLocaleString();
|
|
265
286
|
const rate = (value)=>value == null ? '—' : `${Math.round(value * 100)}%`;
|
|
266
287
|
/** The month's tokens, and what each kind of request spends of them (AGL-2937). */ function TokensSection({ tokens }) {
|
|
@@ -472,7 +493,7 @@ const rate = (value)=>value == null ? '—' : `${Math.round(value * 100)}%`;
|
|
|
472
493
|
});
|
|
473
494
|
}
|
|
474
495
|
const StaffOrgAiCard = ({ orgId })=>{
|
|
475
|
-
var _ref;
|
|
496
|
+
var _ref, _ref1, _ref2, _ref3;
|
|
476
497
|
const { data: user } = useUser();
|
|
477
498
|
// Keyed on who is signed in, not on the user object's identity.
|
|
478
499
|
const signedInUid = (_ref = user == null ? void 0 : user.uid) != null ? _ref : null;
|
|
@@ -481,6 +502,15 @@ const StaffOrgAiCard = ({ orgId })=>{
|
|
|
481
502
|
const [data, setData] = useState(null);
|
|
482
503
|
const [ready, setReady] = useState(false);
|
|
483
504
|
const [error, setError] = useState(null);
|
|
505
|
+
// Bumped after a give-back, so the card re-reads the figures it changed.
|
|
506
|
+
const [version, setVersion] = useState(0);
|
|
507
|
+
const [notice, setNotice] = useState(null);
|
|
508
|
+
const [returning, setReturning] = useState(null);
|
|
509
|
+
const giveBackJob = useCallback((job)=>setReturning({
|
|
510
|
+
mode: 'give',
|
|
511
|
+
jobId: job.id,
|
|
512
|
+
jobCredits: job.creditsSpent
|
|
513
|
+
}), []);
|
|
484
514
|
useEffect(()=>{
|
|
485
515
|
// Mounted only for a confirmed staff reader — the `staffOrg` zone sits
|
|
486
516
|
// inside the page's `StaffOnly`, which renders nothing while the claim
|
|
@@ -518,227 +548,282 @@ const StaffOrgAiCard = ({ orgId })=>{
|
|
|
518
548
|
};
|
|
519
549
|
}, [
|
|
520
550
|
orgId,
|
|
521
|
-
signedInUid
|
|
551
|
+
signedInUid,
|
|
552
|
+
version
|
|
522
553
|
]);
|
|
523
554
|
const name = aiAddonName();
|
|
524
|
-
return /*#__PURE__*/
|
|
555
|
+
return /*#__PURE__*/ _jsxs(CardDisplay, {
|
|
525
556
|
header: name,
|
|
526
557
|
help: pluginDocsHelp('aiMonitoring', {
|
|
527
558
|
anchor: '#the-ai-card',
|
|
528
559
|
excerpt: 'The add-on, the credit pool and its parts, this month’s overage and refusals, generation jobs, tokens and the cache hit rate by kind, the people spending the most, and the margin — for this organization.'
|
|
529
560
|
}),
|
|
561
|
+
HeaderProps: {
|
|
562
|
+
action: /*#__PURE__*/ _jsx(StaffCreditReturnActions, {
|
|
563
|
+
disabled: !data,
|
|
564
|
+
onGive: ()=>setReturning({
|
|
565
|
+
mode: 'give'
|
|
566
|
+
}),
|
|
567
|
+
onReset: ()=>setReturning({
|
|
568
|
+
mode: 'reset'
|
|
569
|
+
})
|
|
570
|
+
})
|
|
571
|
+
},
|
|
530
572
|
contentGutterX: true,
|
|
531
573
|
contentGutterY: true,
|
|
532
|
-
children:
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
574
|
+
children: [
|
|
575
|
+
data ? /*#__PURE__*/ _jsx(StaffCreditReturnDialog, {
|
|
576
|
+
open: returning !== null,
|
|
577
|
+
mode: (_ref1 = returning == null ? void 0 : returning.mode) != null ? _ref1 : 'give',
|
|
578
|
+
target: {
|
|
579
|
+
orgId
|
|
580
|
+
},
|
|
581
|
+
workspace: {
|
|
582
|
+
used: data.pool.usedCredits,
|
|
583
|
+
limit: data.pool.totalCredits
|
|
584
|
+
},
|
|
585
|
+
account: data.account ? {
|
|
586
|
+
used: data.account.usedCredits,
|
|
587
|
+
limit: data.account.limitCredits
|
|
588
|
+
} : null,
|
|
589
|
+
jobId: (_ref2 = returning == null ? void 0 : returning.jobId) != null ? _ref2 : null,
|
|
590
|
+
jobCredits: (_ref3 = returning == null ? void 0 : returning.jobCredits) != null ? _ref3 : null,
|
|
591
|
+
onClose: ()=>setReturning(null),
|
|
592
|
+
onReturned: (message)=>{
|
|
593
|
+
setReturning(null);
|
|
594
|
+
setNotice(message);
|
|
595
|
+
setVersion((current)=>current + 1);
|
|
596
|
+
}
|
|
597
|
+
}) : null,
|
|
598
|
+
notice ? /*#__PURE__*/ _jsx(Alert, {
|
|
599
|
+
severity: "success",
|
|
600
|
+
onClose: ()=>setNotice(null),
|
|
601
|
+
sx: {
|
|
602
|
+
mb: 2
|
|
603
|
+
},
|
|
604
|
+
children: notice
|
|
605
|
+
}) : null,
|
|
606
|
+
!ready ? /*#__PURE__*/ _jsx(Typography, {
|
|
607
|
+
variant: "body2",
|
|
608
|
+
color: "text.secondary",
|
|
609
|
+
children: 'Loading…'
|
|
610
|
+
}) : error || !data ? /*#__PURE__*/ _jsx(Alert, {
|
|
611
|
+
severity: "warning",
|
|
612
|
+
children: `Could not read this organization’s AI usage — ${error != null ? error : 'a failed read'}, not zero usage.`
|
|
613
|
+
}) : /*#__PURE__*/ _jsxs(Stack, {
|
|
614
|
+
spacing: 2,
|
|
615
|
+
children: [
|
|
616
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
617
|
+
spacing: 0.5,
|
|
618
|
+
children: [
|
|
619
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
620
|
+
variant: "overline",
|
|
621
|
+
color: "text.secondary",
|
|
622
|
+
children: 'Add-on'
|
|
623
|
+
}),
|
|
624
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
625
|
+
direction: "row",
|
|
626
|
+
spacing: 1,
|
|
627
|
+
sx: {
|
|
628
|
+
alignItems: 'center',
|
|
629
|
+
flexWrap: 'wrap'
|
|
630
|
+
},
|
|
631
|
+
children: [
|
|
632
|
+
/*#__PURE__*/ _jsx(Chip, {
|
|
633
|
+
size: "small",
|
|
634
|
+
color: data.addon.on ? 'primary' : 'default',
|
|
635
|
+
label: data.addon.on ? `${name} on` : `${name} off`
|
|
636
|
+
}),
|
|
637
|
+
data.addon.priceUsd !== null ? /*#__PURE__*/ _jsx(Typography, {
|
|
638
|
+
variant: "body2",
|
|
639
|
+
children: `${usd(data.addon.priceUsd)}/mo on this plan`
|
|
640
|
+
}) : /*#__PURE__*/ _jsx(Typography, {
|
|
641
|
+
variant: "body2",
|
|
642
|
+
color: "text.secondary",
|
|
643
|
+
children: 'Not sold on this plan'
|
|
644
|
+
}),
|
|
645
|
+
data.addon.on ? /*#__PURE__*/ _jsx(Typography, {
|
|
646
|
+
variant: "body2",
|
|
647
|
+
color: "text.secondary",
|
|
648
|
+
children: data.addon.since ? `since ${when(data.addon.since)}` : data.addon.sinceSource === 'unavailable' ? 'since — (Stripe not reachable)' : 'since — (no subscription item)'
|
|
649
|
+
}) : null
|
|
650
|
+
]
|
|
651
|
+
})
|
|
652
|
+
]
|
|
653
|
+
}),
|
|
654
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
655
|
+
spacing: 0.5,
|
|
656
|
+
children: [
|
|
657
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
658
|
+
variant: "overline",
|
|
659
|
+
color: "text.secondary",
|
|
660
|
+
children: `Credit pool · ${data.month}`
|
|
661
|
+
}),
|
|
662
|
+
data.pool.totalCredits === null && data.pool.uncapped ? /*#__PURE__*/ _jsx(Typography, {
|
|
663
|
+
variant: "body2",
|
|
664
|
+
color: "text.secondary",
|
|
665
|
+
children: 'Uncapped staff comp — no AI credit band. Bounded only by the message cap and an operator’s explicit spend ceiling.'
|
|
666
|
+
}) : data.pool.totalCredits === null ? /*#__PURE__*/ _jsx(Typography, {
|
|
667
|
+
variant: "body2",
|
|
668
|
+
color: "text.secondary",
|
|
669
|
+
children: 'No AI credit band on this plan — bounded by the message cap and the operator backstop.'
|
|
670
|
+
}) : /*#__PURE__*/ _jsx(Typography, {
|
|
671
|
+
variant: "body2",
|
|
672
|
+
children: `${credits(data.pool.totalCredits)} credits = ${poolPartsSentence(data.pool)}`
|
|
673
|
+
}),
|
|
674
|
+
/*#__PURE__*/ _jsxs(Typography, {
|
|
675
|
+
variant: "body2",
|
|
676
|
+
children: [
|
|
677
|
+
`Used ${credits(data.pool.usedCredits)} credits (${usd(data.pool.providerUsd)} provider spend)`,
|
|
678
|
+
data.pool.remainingCredits !== null ? ` · ${credits(data.pool.remainingCredits)} remaining` : ''
|
|
679
|
+
]
|
|
680
|
+
}),
|
|
681
|
+
data.pool.returnedCredits ? /*#__PURE__*/ _jsx(Typography, {
|
|
682
|
+
variant: "body2",
|
|
683
|
+
color: "text.secondary",
|
|
684
|
+
children: `${credits(data.pool.returnedCredits)} credits given back this month — already taken off the figure above.`
|
|
685
|
+
}) : null,
|
|
686
|
+
data.account ? /*#__PURE__*/ _jsx(Typography, {
|
|
687
|
+
variant: "body2",
|
|
688
|
+
children: `Owner’s Free allowance: ${credits(data.account.usedCredits)} of ${credits(data.account.limitCredits)} used across their free workspaces` + (data.account.returnedCredits ? ` (${credits(data.account.returnedCredits)} given back)` : '')
|
|
689
|
+
}) : null,
|
|
690
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
691
|
+
variant: "body2",
|
|
692
|
+
color: "text.secondary",
|
|
693
|
+
children: `Projected month-end at this pace: ${credits(data.pool.projectedCredits)} credits (${usd(data.pool.projectedUsd)}) · ${data.pool.messages.toLocaleString()} model turns, ${data.pool.deflected.toLocaleString()} answered from the docs`
|
|
694
|
+
})
|
|
695
|
+
]
|
|
696
|
+
}),
|
|
697
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
698
|
+
spacing: 0.5,
|
|
699
|
+
children: [
|
|
700
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
701
|
+
variant: "overline",
|
|
702
|
+
color: "text.secondary",
|
|
703
|
+
children: 'Overage'
|
|
704
|
+
}),
|
|
705
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
706
|
+
variant: "body2",
|
|
707
|
+
children: `${credits(data.overage.overageCredits)} credits over the band · ${usd(data.overage.accruedUsd)} accrued`
|
|
708
|
+
}),
|
|
709
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
710
|
+
variant: "body2",
|
|
711
|
+
color: "text.secondary",
|
|
712
|
+
children: overageStateSentence(data.overage, data.pool.uncapped === true)
|
|
713
|
+
})
|
|
714
|
+
]
|
|
715
|
+
}),
|
|
716
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
717
|
+
spacing: 0.5,
|
|
718
|
+
children: [
|
|
719
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
720
|
+
variant: "overline",
|
|
721
|
+
color: "text.secondary",
|
|
722
|
+
children: `Refusals this month · ${data.refusals.total.toLocaleString()}`
|
|
723
|
+
}),
|
|
724
|
+
/*#__PURE__*/ _jsx(RefusalsRow, {
|
|
725
|
+
refusals: data.refusals
|
|
726
|
+
})
|
|
727
|
+
]
|
|
728
|
+
}),
|
|
729
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
730
|
+
spacing: 0.5,
|
|
731
|
+
children: [
|
|
732
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
733
|
+
variant: "overline",
|
|
734
|
+
color: "text.secondary",
|
|
735
|
+
children: 'Generation jobs'
|
|
736
|
+
}),
|
|
737
|
+
/*#__PURE__*/ _jsx(JobsSection, {
|
|
738
|
+
jobs: data.jobs,
|
|
739
|
+
onGiveBack: giveBackJob
|
|
740
|
+
})
|
|
741
|
+
]
|
|
742
|
+
}),
|
|
743
|
+
data.tokens ? /*#__PURE__*/ _jsxs(Stack, {
|
|
744
|
+
spacing: 0.5,
|
|
745
|
+
children: [
|
|
746
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
747
|
+
variant: "overline",
|
|
748
|
+
color: "text.secondary",
|
|
749
|
+
children: `Tokens · ${data.month}`
|
|
750
|
+
}),
|
|
751
|
+
/*#__PURE__*/ _jsx(TokensSection, {
|
|
752
|
+
tokens: data.tokens
|
|
753
|
+
})
|
|
754
|
+
]
|
|
755
|
+
}) : null,
|
|
756
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
757
|
+
spacing: 0.5,
|
|
758
|
+
children: [
|
|
759
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
760
|
+
variant: "overline",
|
|
761
|
+
color: "text.secondary",
|
|
762
|
+
children: 'Top users this month'
|
|
763
|
+
}),
|
|
764
|
+
data.users.length === 0 ? /*#__PURE__*/ _jsx(Typography, {
|
|
765
|
+
variant: "body2",
|
|
766
|
+
color: "text.secondary",
|
|
767
|
+
children: 'No AI usage attributed to a person this month.'
|
|
768
|
+
}) : /*#__PURE__*/ _jsx(TopUsersSection, {
|
|
769
|
+
users: data.users
|
|
770
|
+
})
|
|
771
|
+
]
|
|
772
|
+
}),
|
|
773
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
774
|
+
spacing: 0.5,
|
|
775
|
+
children: [
|
|
776
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
777
|
+
variant: "overline",
|
|
778
|
+
color: "text.secondary",
|
|
779
|
+
children: 'Margin'
|
|
780
|
+
}),
|
|
781
|
+
/*#__PURE__*/ _jsxs(Alert, {
|
|
782
|
+
severity: marginTone(data.margin),
|
|
783
|
+
children: [
|
|
784
|
+
`Spend ${usd(data.margin.spendUsd)} against ${usd(data.margin.revenueUsd)} in — ` + `${usd(data.margin.addonRevenueUsd)} add-on, ${usd(data.margin.planAssistShareUsd)} plan assist share, ` + `${usd(data.margin.overageRevenueUsd)} overage.`,
|
|
785
|
+
data.margin.underwater ? ' Spend exceeds the add-on plus the plan’s assist share.' : '',
|
|
786
|
+
data.margin.multiple >= 1 ? ` ${data.margin.multiple}× the ${usd(data.margin.thresholdUsd)} staff review threshold.` : ''
|
|
787
|
+
]
|
|
788
|
+
}),
|
|
789
|
+
data.margin.contribution.marginPct !== null ? /*#__PURE__*/ _jsx(Typography, {
|
|
790
|
+
variant: "caption",
|
|
791
|
+
color: "text.secondary",
|
|
792
|
+
children: `Whole-org contribution margin ${Math.round(data.margin.contribution.marginPct * 100)}% on the ${data.margin.contribution.month} rollup with this month’s AI spend.`
|
|
793
|
+
}) : null
|
|
794
|
+
]
|
|
795
|
+
}),
|
|
796
|
+
/*#__PURE__*/ _jsxs(Stack, {
|
|
797
|
+
spacing: 0.5,
|
|
798
|
+
children: [
|
|
799
|
+
/*#__PURE__*/ _jsx(Typography, {
|
|
800
|
+
variant: "overline",
|
|
801
|
+
color: "text.secondary",
|
|
802
|
+
children: 'Actions'
|
|
803
|
+
}),
|
|
804
|
+
/*#__PURE__*/ _jsxs(Typography, {
|
|
805
|
+
variant: "body2",
|
|
806
|
+
children: [
|
|
807
|
+
'Credit override and feature toggles: ',
|
|
808
|
+
/*#__PURE__*/ _jsx(AppLink, {
|
|
809
|
+
href: buildRoute(Route.ADMIN_ORGS),
|
|
810
|
+
underline: "hover",
|
|
811
|
+
children: 'the entitlement override editor'
|
|
812
|
+
}),
|
|
813
|
+
' (also under Staff actions above). Pause AI for this org: ',
|
|
814
|
+
/*#__PURE__*/ _jsx(AppLink, {
|
|
815
|
+
href: buildRoute(Route.ADMIN_LOCKDOWN),
|
|
816
|
+
underline: "hover",
|
|
817
|
+
children: 'Lockdown'
|
|
818
|
+
}),
|
|
819
|
+
', feature keys ai-assist and ai-generate scoped to the org.'
|
|
820
|
+
]
|
|
821
|
+
})
|
|
822
|
+
]
|
|
823
|
+
})
|
|
824
|
+
]
|
|
825
|
+
})
|
|
826
|
+
]
|
|
742
827
|
});
|
|
743
828
|
};
|
|
744
829
|
StaffOrgAiCard.displayName = 'StaffOrgAiCard';
|