@naisys/erp 3.0.0-beta.50 → 3.0.0-beta.52

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.
@@ -1,5 +1,5 @@
1
1
  import { r as __toESM } from "./rolldown-runtime-CvHMtSRF.js";
2
- import { $ as string, $t as Popover, A as IconPlus, At as Modal, B as IconCheck, Bt as Card, C as IconCopy, Ct as Stack, D as IconUpload, Dt as PasswordInput, E as IconUser, Et as Tooltip, F as IconLayoutSidebarLeftCollapse, Ft as Drawer, G as require_semver, Gt as AppShell, H as IconApi, Ht as Badge, I as IconInfoCircle, It as Divider, J as array, Jt as Alert, K as ZodIssueCode, Kt as Anchor, L as IconFile, Lt as Container, M as IconLogout, Mt as Textarea, N as IconListDetails, Nt as Image, O as IconTrash, Ot as Pagination, P as IconLayoutSidebarLeftExpand, Pt as FileButton, Q as record, Qt as Loader, R as IconEye$1, Rt as Code, S as IconDownload, St as Switch, T as IconX, Tt as SegmentedControl, U as IconAlertTriangle, Ut as Autocomplete, V as IconArrowBackUp, Vt as Button, W as IconAlertCircle, Wt as Checkbox, X as number, Xt as Group, Y as boolean, Yt as Accordion, Z as object, Zt as ActionIcon, _ as Markdown, _t as DatesProvider, a as _undefined, an as useDebouncedValue, at as Outlet, b as IconEye, bt as Tabs, c as boolean$1, cn as require_react, ct as useLocation, d as object$1, dt as useParams, en as UnstyledButton, et as union, f as string$1, ft as useSearchParams, g as remarkGfm, gt as DateInput, h as diffWordsWithSpace, ht as DateTimePicker, i as _null, in as useDisclosure, it as Navigate, j as IconNote, jt as Menu, k as IconRobot, kt as NumberInput, l as literal, lt as useNavigate, m as datetime, mt as notifications, n as string$2, nn as Box, nt as BrowserRouter, o as any, on as require_jsx_runtime, ot as Route, p as union$1, pt as Notifications, q as _enum, qt as Text, r as _enum$1, rn as MantineProvider, rt as Link, s as array$1, sn as require_client, st as Routes, t as number$1, tn as ScrollArea, tt as unknown, u as number$2, ut as useOutletContext, v as IconRefresh, vt as Title, w as useForm, wt as Select, x as IconEyeOff, xt as Table, y as IconPhoto, yt as TextInput, z as IconChevronDown, zt as Center } from "./vendor-Co7ZCNxO.js";
2
+ import { $ as record, $t as Loader, A as IconPlus, At as NumberInput, B as IconCheck, Bt as Center, C as IconCopy, Ct as Switch, D as IconUpload, Dt as Tooltip, E as IconUser, Et as SegmentedControl, F as IconLayoutSidebarLeftCollapse, Ft as FileButton, G as require_semver, Gt as Checkbox, H as IconApi, Ht as Button, I as IconInfoCircle, It as Drawer, J as _enum, Jt as Text, K as require_dist, Kt as AppShell, L as IconFile, Lt as Divider, M as IconLogout, Mt as Menu, N as IconListDetails, Nt as Textarea, O as IconTrash, Ot as PasswordInput, P as IconLayoutSidebarLeftExpand, Pt as Image, Q as object, Qt as ActionIcon, R as IconEye$1, Rt as Container, S as IconDownload, St as Table, T as IconX, Tt as Select, U as IconAlertTriangle, Ut as Badge, V as IconArrowBackUp, Vt as Card, W as IconAlertCircle, Wt as Autocomplete, X as boolean, Xt as Accordion, Y as array, Yt as Alert, Z as number, Zt as Group, _ as Markdown, _t as DateInput, a as _undefined, an as useDisclosure, at as Navigate, b as IconEye, bt as TextInput, c as boolean$1, cn as require_client, ct as Routes, d as object$1, dt as useOutletContext, en as Popover, et as string, f as string$1, ft as useParams, g as remarkGfm, gt as DateTimePicker, h as diffWordsWithSpace, ht as notifications, i as _null, in as MantineProvider, it as Link, j as IconNote, jt as Modal, k as IconRobot, kt as Pagination, l as literal, ln as require_react, lt as useLocation, m as datetime, mt as Notifications, n as string$2, nn as ScrollArea, nt as unknown, o as any, on as useDebouncedValue, ot as Outlet, p as union$1, pt as useSearchParams, q as ZodIssueCode, qt as Anchor, r as _enum$1, rn as Box, rt as BrowserRouter, s as array$1, sn as require_jsx_runtime, st as Route, t as number$1, tn as UnstyledButton, tt as union, u as number$2, ut as useNavigate, v as IconRefresh, vt as DatesProvider, w as useForm, wt as Stack, x as IconEyeOff, xt as Tabs, y as IconPhoto, yt as Title, z as IconChevronDown, zt as Code } from "./vendor-CJ0ET9hP.js";
3
3
  //#region \0vite/modulepreload-polyfill.js
4
4
  (function polyfill() {
5
5
  const relList = document.createElement("link").relList;
@@ -42,6 +42,33 @@ var URL_SAFE_KEY_MESSAGE = "Must contain only letters, numbers, hyphens, and und
42
42
  /** Target megapixels for screenshots sent to LLMs during computer use */
43
43
  var TARGET_MEGAPIXELS = 1.1;
44
44
  //#endregion
45
+ //#region ../../../packages/common/dist/agent/scheduleUtils.js
46
+ var import_dist = require_dist();
47
+ var ScheduleEntrySchema = object({
48
+ name: string().min(1, "Name is required").regex(URL_SAFE_KEY_REGEX, URL_SAFE_KEY_MESSAGE).describe("Unique identifier for this schedule within the agent"),
49
+ cron: string().min(1, "Cron expression is required").refine((expr) => validateCron(expr).ok, { message: "Invalid cron expression" }).describe("Standard 5-field cron expression in the hub's local timezone"),
50
+ enabled: boolean().optional().describe("When false, the schedule is paused but kept for editing"),
51
+ prompt: string().max(2e3, "Prompt must be at most 2000 characters").optional().describe("Chat message sent to the agent when the schedule fires. Falls back to the schedule name when empty"),
52
+ initiator: string().regex(URL_SAFE_KEY_REGEX, URL_SAFE_KEY_MESSAGE).optional().describe("Username the fire message is sent from. The agent reports back to this user when done, letting that agent run its own post-processing. When unset, defaults to the agent's lead, or admin if it has no lead")
53
+ });
54
+ function validateCron(expression) {
55
+ const fields = expression.trim().split(/\s+/).filter(Boolean);
56
+ if (fields.length !== 5) return {
57
+ ok: false,
58
+ error: `Expected 5 fields (min hour day month weekday), got ${fields.length}`
59
+ };
60
+ try {
61
+ import_dist.CronExpressionParser.parse(expression);
62
+ return { ok: true };
63
+ } catch (err) {
64
+ return {
65
+ ok: false,
66
+ error: err instanceof Error ? err.message : String(err)
67
+ };
68
+ }
69
+ }
70
+ object({ schedules: array(unknown()).optional() }).loose();
71
+ //#endregion
45
72
  //#region ../../../packages/common/dist/agent/agentConfigFile.js
46
73
  var commandProtectionValues = [
47
74
  "none",
@@ -82,7 +109,20 @@ object({
82
109
  multipleCommandsEnabled: boolean().optional().describe("Allow the LLM to run multiple commands per turn. Faster but the LLM may get ahead of itself and produce errors. Disable for weaker LLMs."),
83
110
  workspacesEnabled: boolean().optional().describe("Experimental: Allows the LLM to pin files to the end of the context. Each turn the agent sees the latest version without old versions taking up context space"),
84
111
  controlDesktop: boolean().optional().describe(`Allow the agent to operate the desktop GUI. Requires a vision-capable model; computer-use models are ideal. Screens over ${TARGET_MEGAPIXELS}MP will be downscaled.`),
85
- supervisorApiHints: boolean().optional().describe("Tell the agent in its system message how to call the supervisor API to manage NAISYS agents, hosts, variables, models, users, etc. Useful for admin / assistant agents")
112
+ supervisorApiHints: boolean().optional().describe("Tell the agent in its system message how to call the supervisor API to manage NAISYS agents, hosts, variables, models, users, etc. Useful for admin / assistant agents"),
113
+ schedules: array(ScheduleEntrySchema).optional().superRefine((schedules, ctx) => {
114
+ if (!schedules) return;
115
+ const seen = /* @__PURE__ */ new Set();
116
+ for (let i = 0; i < schedules.length; i++) {
117
+ const name = schedules[i].name;
118
+ if (seen.has(name)) ctx.addIssue({
119
+ code: "custom",
120
+ path: [i, "name"],
121
+ message: `Duplicate schedule name "${name}"`
122
+ });
123
+ seen.add(name);
124
+ }
125
+ }).describe("Cron schedules that wake the agent and deliver a chat from admin at fire time. Cron runs in the hub's local timezone. If the agent is offline, the chat queues and dedupes per schedule name.")
86
126
  });
87
127
  //#endregion
88
128
  //#region ../../../packages/common/dist/auth/codexOAuth.js
@@ -299,6 +339,15 @@ LlmApiType.None, LlmApiType.None, LlmApiType.None, LlmApiType.Mock, LlmApiType.M
299
339
  reasoningLevel: "medium"
300
340
  }), LlmApiType.Google, LlmApiType.Google, LlmApiType.Google, LlmApiType.Anthropic, LlmApiType.Anthropic, LlmApiType.Anthropic;
301
341
  //#endregion
342
+ //#region ../../../packages/common/dist/utils/collections.js
343
+ /** Build a plain object record from map entries or projected items. */
344
+ function toRecord(source, keyFn, valueFn) {
345
+ const record = {};
346
+ if (keyFn && valueFn) for (const item of source) record[keyFn(item)] = valueFn(item);
347
+ else for (const [key, value] of source) record[key] = value;
348
+ return record;
349
+ }
350
+ //#endregion
302
351
  //#region ../../../packages/common/dist/utils/formatFileSize.js
303
352
  /** Format a byte count into a human-readable size string (e.g. "1.2 KB") */
304
353
  function formatFileSize(bytes) {
@@ -307,6 +356,14 @@ function formatFileSize(bytes) {
307
356
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
308
357
  }
309
358
  //#endregion
359
+ //#region ../../../packages/common/dist/utils/formatTokens.js
360
+ /** Compact token count for tight UI surfaces (e.g. "12.3k", "1.5M", "123"). */
361
+ function formatTokens(tokens) {
362
+ if (tokens >= 1e6) return `${(tokens / 1e6).toFixed(1)}M`;
363
+ if (tokens >= 1e3) return `${(tokens / 1e3).toFixed(1)}k`;
364
+ return `${Math.round(tokens)}`;
365
+ }
366
+ //#endregion
310
367
  //#region ../../../packages/common/dist/utils/formatVersion.js
311
368
  var import_semver = /* @__PURE__ */ __toESM(require_semver(), 1);
312
369
  /**
@@ -1556,6 +1613,7 @@ var OperationRunSchema = object$1({
1556
1613
  status: OperationRunStatusEnum,
1557
1614
  assignedTo: string$1().nullable(),
1558
1615
  cost: number$2().nullable(),
1616
+ tokens: number$2().nullable(),
1559
1617
  note: string$1().nullable(),
1560
1618
  completedAt: datetime().nullable(),
1561
1619
  stepSummary: array$1(StepRunSummarySchema).optional(),
@@ -1578,6 +1636,7 @@ object$1({
1578
1636
  status: OperationRunStatusEnum,
1579
1637
  assignedTo: string$1().nullable(),
1580
1638
  cost: number$2().nullable(),
1639
+ tokens: number$2().nullable(),
1581
1640
  note: string$1().nullable(),
1582
1641
  completedAt: datetime().nullable(),
1583
1642
  updatedAt: datetime(),
@@ -2047,6 +2106,7 @@ var LaborTicketSchema = object$1({
2047
2106
  clockIn: datetime(),
2048
2107
  clockOut: datetime().nullable(),
2049
2108
  cost: number$2().nullable(),
2109
+ tokens: number$2().nullable(),
2050
2110
  createdAt: datetime(),
2051
2111
  createdBy: string$1(),
2052
2112
  updatedAt: datetime(),
@@ -3976,7 +4036,7 @@ function editKey(fieldId, setIndex) {
3976
4036
  }
3977
4037
  /** Build edits map from field values */
3978
4038
  function buildEdits(fieldValues) {
3979
- return Object.fromEntries(fieldValues.map((fv) => [editKey(fv.fieldId, fv.setIndex), fv.value]));
4039
+ return toRecord(fieldValues, (fv) => editKey(fv.fieldId, fv.setIndex), (fv) => fv.value);
3980
4040
  }
3981
4041
  function fieldValueEquals(a, b) {
3982
4042
  return JSON.stringify(a) === JSON.stringify(b);
@@ -3984,11 +4044,11 @@ function fieldValueEquals(a, b) {
3984
4044
  function mergeEditsPreservingDirty(previousFieldValues, nextFieldValues, currentEdits) {
3985
4045
  const previousEdits = buildEdits(previousFieldValues);
3986
4046
  const nextEdits = buildEdits(nextFieldValues);
3987
- return Object.fromEntries(Object.entries(nextEdits).map(([key, nextValue]) => {
4047
+ return toRecord(Object.entries(nextEdits), ([key]) => key, ([key, nextValue]) => {
3988
4048
  const currentValue = currentEdits[key];
3989
4049
  const previousValue = previousEdits[key];
3990
- return [key, currentValue !== void 0 && !fieldValueEquals(currentValue, previousValue) ? currentValue : nextValue];
3991
- }));
4050
+ return currentValue !== void 0 && !fieldValueEquals(currentValue, previousValue) ? currentValue : nextValue;
4051
+ });
3992
4052
  }
3993
4053
  /** Get a string value from FieldValue (for scalar fields) */
3994
4054
  function asString(v) {
@@ -6734,7 +6794,8 @@ var OperationSummaryTable = ({ items, loading, linkBuilder }) => {
6734
6794
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Title" }),
6735
6795
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Prerequisites" }),
6736
6796
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Steps" }),
6737
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Cost" })
6797
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Cost" }),
6798
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Tokens" })
6738
6799
  ] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Tbody, { children: items.map((op) => {
6739
6800
  const opLink = linkBuilder(op.seqNo);
6740
6801
  return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Tr, {
@@ -6794,6 +6855,14 @@ var OperationSummaryTable = ({ items, loading, linkBuilder }) => {
6794
6855
  style: cellLinkStyle,
6795
6856
  children: op.cost ? `$${op.cost.toFixed(2)}` : "—"
6796
6857
  })
6858
+ }),
6859
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, {
6860
+ style: { padding: 0 },
6861
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Link, {
6862
+ to: opLink,
6863
+ style: cellLinkStyle,
6864
+ children: op.tokens ? formatTokens(op.tokens) : "—"
6865
+ })
6797
6866
  })
6798
6867
  ]
6799
6868
  }, op.id);
@@ -8171,6 +8240,7 @@ var LaborTicketList = ({ orderKey, runNo, seqNo, refreshKey, showTitle = true, o
8171
8240
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Clock Out" }),
8172
8241
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Duration" }),
8173
8242
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Cost" }),
8243
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, { children: "Tokens" }),
8174
8244
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Th, {})
8175
8245
  ] }) }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Tbody, { children: data.items.map((ticket) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Table.Tr, { children: [
8176
8246
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: ticket.username }),
@@ -8188,6 +8258,7 @@ var LaborTicketList = ({ orderKey, runNo, seqNo, refreshKey, showTitle = true, o
8188
8258
  }) }),
8189
8259
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: formatDuration(ticket.clockIn, ticket.clockOut) }),
8190
8260
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: ticket.cost != null ? `$${ticket.cost.toFixed(2)}` : "—" }),
8261
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: ticket.tokens != null ? formatTokens(ticket.tokens) : "—" }),
8191
8262
  /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Table.Td, { children: hasActionTemplate(data._actionTemplates, "deleteTicket") && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ActionIcon, {
8192
8263
  size: "xs",
8193
8264
  variant: "subtle",
@@ -8823,7 +8894,8 @@ var OperationRunDetail = () => {
8823
8894
  " on",
8824
8895
  " ",
8825
8896
  new Date(opRun.updatedAt).toLocaleString(),
8826
- opRun.cost ? ` for $${opRun.cost.toFixed(2)}` : ""
8897
+ opRun.cost ? ` for $${opRun.cost.toFixed(2)}` : "",
8898
+ opRun.tokens ? ` (${formatTokens(opRun.tokens)})` : ""
8827
8899
  ]
8828
8900
  }), (() => {
8829
8901
  const reason = formatDisabledReason(reopenAction.disabledReason);