@docyrus/ui-pro-ai-assistant 0.4.8 → 0.5.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.
@@ -1,11 +1,15 @@
1
1
  import { type DataSourceField } from '../lib/assistant-config';
2
2
  export interface ResolvedDataSource {
3
3
  name?: string;
4
+ type?: string;
4
5
  appSlug: string;
5
6
  dsSlug: string;
6
7
  labelField?: {
7
8
  slug: string;
8
9
  };
10
+ idField?: {
11
+ slug: string;
12
+ };
9
13
  }
10
14
  export declare function clearRecordFieldsCache(): void;
11
15
  export interface UseResolvedRecordFieldsResult {
package/dist/index.js CHANGED
@@ -4957,12 +4957,14 @@ var USER_TYPES = /* @__PURE__ */ new Set([
4957
4957
  "userSelect",
4958
4958
  "userMultiSelect"
4959
4959
  ]);
4960
+ var RELATION_TYPES = /* @__PURE__ */ new Set(["field-relation", "relation"]);
4960
4961
  var CACHE_TTL_MS = 10 * 60 * 1e3;
4961
4962
  var USERS_PAGE_LIMIT = 200;
4962
4963
  var USERS_PAGE_CAP = 5;
4963
4964
  var metaCache = /* @__PURE__ */ new Map();
4964
4965
  var enumsCache = /* @__PURE__ */ new Map();
4965
4966
  var usersCache = /* @__PURE__ */ new Map();
4967
+ var relationCache = /* @__PURE__ */ new Map();
4966
4968
  function getOrFetch(cache, key, loader) {
4967
4969
  const now = Date.now();
4968
4970
  const cached = cache.get(key);
@@ -4998,9 +5000,11 @@ async function fetchMeta(apiClient, dataSourceId, baseUrl, getDataSourceSchema)
4998
5000
  return {
4999
5001
  dataSource: {
5000
5002
  name: ds.name,
5003
+ type: ds.type,
5001
5004
  appSlug,
5002
5005
  dsSlug,
5003
- labelField: ds.label_field
5006
+ labelField: ds.label_field || ds.labelField,
5007
+ idField: ds.id_field || ds.idField
5004
5008
  },
5005
5009
  fields: dsFields
5006
5010
  };
@@ -5023,7 +5027,15 @@ async function fetchEnums(apiClient, dataSourceId, baseUrl) {
5023
5027
  id: opt.id,
5024
5028
  name: opt.name,
5025
5029
  color: opt.color,
5026
- icon: opt.icon
5030
+ icon: opt.icon,
5031
+ parent: opt.parent || opt.parentId || opt.parent_id,
5032
+ slug: opt.slug,
5033
+ sort_order: opt.sortOrder ?? opt.sort_order,
5034
+ active: opt.active,
5035
+ is_final_option: opt.isFinalOption ?? opt.is_final_option,
5036
+ force_description: opt.forceDescription ?? opt.force_description,
5037
+ force_followup_date: opt.forceFollowupDate ?? opt.force_followup_date,
5038
+ description: opt.description
5027
5039
  });
5028
5040
  }
5029
5041
  return byFieldId.size > 0 ? byFieldId : null;
@@ -5046,7 +5058,7 @@ async function fetchUsers(apiClient, baseUrl) {
5046
5058
  const id = u.id || u.user_id;
5047
5059
  if (!id || seen.has(id)) continue;
5048
5060
  seen.add(id);
5049
- added += 1;
5061
+ added++;
5050
5062
  const nameParts = [u.firstname, u.lastname].filter(Boolean).join(" ");
5051
5063
  all3.push({
5052
5064
  id,
@@ -5059,6 +5071,61 @@ async function fetchUsers(apiClient, baseUrl) {
5059
5071
  return all3.length > 0 ? all3 : null;
5060
5072
  });
5061
5073
  }
5074
+ function resolveDisplayName(record, labelSlug) {
5075
+ const labelValue = record[labelSlug];
5076
+ if (typeof labelValue === "string" && labelValue) return labelValue;
5077
+ if (labelValue && typeof labelValue === "object" && "name" in labelValue) {
5078
+ return labelValue.name;
5079
+ }
5080
+ const nameValue = record.name;
5081
+ if (typeof nameValue === "string" && nameValue) return nameValue;
5082
+ if (nameValue && typeof nameValue === "object" && "name" in nameValue) {
5083
+ return nameValue.name;
5084
+ }
5085
+ return record.title || record.label || record.display_name || record.id;
5086
+ }
5087
+ var RELATION_ITEMS_LIMIT = 50;
5088
+ async function fetchRelationRecords(apiClient, relationDataSourceId, baseUrl, getDataSourceSchema) {
5089
+ return getOrFetch(relationCache, `${baseUrl}::${relationDataSourceId}`, async () => {
5090
+ const relMeta = await fetchMeta(apiClient, relationDataSourceId, baseUrl, getDataSourceSchema);
5091
+ if (!relMeta) return null;
5092
+ const {
5093
+ appSlug,
5094
+ dsSlug,
5095
+ labelField,
5096
+ idField,
5097
+ type: dsType
5098
+ } = relMeta.dataSource;
5099
+ const idSlug = idField?.slug || "id";
5100
+ const labelSlug = labelField?.slug;
5101
+ const columns = dsType === "simple" ? ["name", "id", "autonumber_id"] : [idSlug];
5102
+ if (labelSlug && !columns.includes(labelSlug)) {
5103
+ columns.push(labelSlug);
5104
+ }
5105
+ if (!columns.includes("name")) {
5106
+ columns.push("name");
5107
+ }
5108
+ const res = await apiClient.get(
5109
+ `/apps/${appSlug}/data-sources/${dsSlug}/items`,
5110
+ {
5111
+ limit: RELATION_ITEMS_LIMIT,
5112
+ columns: columns.join(","),
5113
+ dataSourceId: relationDataSourceId,
5114
+ fullCount: false
5115
+ }
5116
+ );
5117
+ if (!res.success) return null;
5118
+ const payload = res.data;
5119
+ const items2 = Array.isArray(payload) ? payload : payload?.items ?? payload?.data;
5120
+ if (!Array.isArray(items2) || items2.length === 0) return null;
5121
+ return items2.map((record) => ({
5122
+ id: record.id,
5123
+ name: resolveDisplayName(record, labelSlug || "name"),
5124
+ icon: record.icon || void 0,
5125
+ color: record.color || void 0
5126
+ }));
5127
+ });
5128
+ }
5062
5129
  function useResolvedRecordFields(dataSourceId, recordSlugs) {
5063
5130
  const apiClient = useApiClient();
5064
5131
  const config3 = useAssistantConfig();
@@ -5072,12 +5139,8 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5072
5139
  );
5073
5140
  const apiClientRef = useRef(apiClient);
5074
5141
  const configRef = useRef(config3);
5075
- useEffect(() => {
5076
- apiClientRef.current = apiClient;
5077
- });
5078
- useEffect(() => {
5079
- configRef.current = config3;
5080
- });
5142
+ apiClientRef.current = apiClient;
5143
+ configRef.current = config3;
5081
5144
  const baseUrl = config3.apiBaseUrl;
5082
5145
  useEffect(() => {
5083
5146
  if (!dataSourceId) {
@@ -5086,7 +5149,7 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5086
5149
  }
5087
5150
  let cancelled = false;
5088
5151
  setLoading(true);
5089
- (async () => {
5152
+ const run = async () => {
5090
5153
  const meta = await fetchMeta(
5091
5154
  apiClientRef.current,
5092
5155
  dataSourceId,
@@ -5106,26 +5169,44 @@ function useResolvedRecordFields(dataSourceId, recordSlugs) {
5106
5169
  }
5107
5170
  const hasSelectFields = displayFields.some((f) => SELECT_TYPES.has(f.type));
5108
5171
  const hasUserFields = displayFields.some((f) => USER_TYPES.has(f.type));
5109
- let enumsPromise = Promise.resolve(null);
5110
- let usersPromise = Promise.resolve(null);
5111
- if (hasSelectFields) enumsPromise = fetchEnums(apiClientRef.current, dataSourceId, baseUrl);
5112
- if (hasUserFields) usersPromise = fetchUsers(apiClientRef.current, baseUrl);
5113
- const [enums, users] = await Promise.all([enumsPromise, usersPromise]);
5172
+ const relationDsIds = [
5173
+ ...new Set(
5174
+ displayFields.filter((f) => RELATION_TYPES.has(f.type) && f.relation_data_source_id).map((f) => f.relation_data_source_id)
5175
+ )
5176
+ ];
5177
+ const enumsPromise = hasSelectFields ? fetchEnums(apiClientRef.current, dataSourceId, baseUrl) : Promise.resolve(null);
5178
+ const usersPromise = hasUserFields ? fetchUsers(apiClientRef.current, baseUrl) : Promise.resolve(null);
5179
+ const relationPromises = relationDsIds.map((relDsId) => fetchRelationRecords(apiClientRef.current, relDsId, baseUrl, configRef.current.getDataSourceSchema).then((options3) => [relDsId, options3]));
5180
+ const [enums, users, ...relationResults] = await Promise.all([enumsPromise, usersPromise, ...relationPromises]);
5114
5181
  if (cancelled) return;
5182
+ const relationMap = /* @__PURE__ */ new Map();
5183
+ for (const [relDsId, options3] of relationResults) {
5184
+ if (options3) relationMap.set(relDsId, options3);
5185
+ }
5115
5186
  const enrichedFields = displayFields.map((f) => {
5116
- if (enums && SELECT_TYPES.has(f.type) && enums.has(f.id)) {
5117
- return { ...f, enumOptions: enums.get(f.id) };
5187
+ if (SELECT_TYPES.has(f.type)) {
5188
+ if (enums && enums.has(f.id)) {
5189
+ return { ...f, enumOptions: enums.get(f.id) };
5190
+ }
5191
+ const inlineData = f.data || f.options?.data || f.options?.editorOptions?.data;
5192
+ if (Array.isArray(inlineData) && inlineData.length > 0) {
5193
+ return { ...f, enumOptions: inlineData };
5194
+ }
5118
5195
  }
5119
5196
  if (users && USER_TYPES.has(f.type)) {
5120
5197
  return { ...f, enumOptions: users };
5121
5198
  }
5199
+ if (RELATION_TYPES.has(f.type) && f.relation_data_source_id && relationMap.has(f.relation_data_source_id)) {
5200
+ return { ...f, enumOptions: relationMap.get(f.relation_data_source_id) };
5201
+ }
5122
5202
  return f;
5123
5203
  });
5124
5204
  setFields(enrichedFields);
5125
5205
  setDataSource(meta.dataSource);
5126
5206
  setResolved(true);
5127
5207
  setLoading(false);
5128
- })();
5208
+ };
5209
+ void run();
5129
5210
  return () => {
5130
5211
  cancelled = true;
5131
5212
  };
@@ -10186,12 +10267,12 @@ function UpdateRecord({
10186
10267
  useEffect(() => {
10187
10268
  if (!dataSource || !recordId || isBatch) return;
10188
10269
  let cancelled = false;
10189
- (async () => {
10270
+ const run = async () => {
10190
10271
  const { appSlug, dsSlug, labelField } = dataSource;
10191
10272
  const columns = ["autonumber_id", labelField?.slug].filter(Boolean);
10192
10273
  const endpoint = `/apps/${appSlug}/data-sources/${dsSlug}/items/${recordId}`;
10193
10274
  try {
10194
- const result = await apiClient.get(endpoint, { columns });
10275
+ const result = await apiClient.get(endpoint, { columns: columns.join(",") });
10195
10276
  if (!cancelled && result.success && result.data) {
10196
10277
  setExistingRecord(result.data);
10197
10278
  }
@@ -10200,7 +10281,8 @@ function UpdateRecord({
10200
10281
  console.warn("[update-record] header fetch failed", err);
10201
10282
  }
10202
10283
  }
10203
- })();
10284
+ };
10285
+ void run();
10204
10286
  return () => {
10205
10287
  cancelled = true;
10206
10288
  };
@@ -30577,7 +30659,7 @@ var AssistantProjectDetailView = ({
30577
30659
  showToolbar: true
30578
30660
  }
30579
30661
  ) }),
30580
- /* @__PURE__ */ jsx("div", { className: "mt-4", children: /* @__PURE__ */ jsxs(Tabs$1, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [
30662
+ /* @__PURE__ */ jsx("div", { className: "mt-8", children: /* @__PURE__ */ jsxs(Tabs$1, { value: activeTab, onValueChange: setActiveTab, className: "w-full", children: [
30581
30663
  /* @__PURE__ */ jsxs(TabsList$1, { className: "grid w-full grid-cols-3", children: [
30582
30664
  /* @__PURE__ */ jsx(TabsTrigger$1, { value: "sessions", children: t("tabs.sessions") }),
30583
30665
  /* @__PURE__ */ jsx(TabsTrigger$1, { value: "works", children: t("tabs.works") }),
@@ -30712,6 +30794,7 @@ var AssistantProjectsPanel = ({
30712
30794
  onEditProject,
30713
30795
  onDeleteProject,
30714
30796
  compact = false,
30797
+ sidebarOffset = false,
30715
30798
  t
30716
30799
  }) => {
30717
30800
  const filtered = projects.filter((p) => {
@@ -30719,10 +30802,10 @@ var AssistantProjectsPanel = ({
30719
30802
  const q = searchQuery.toLowerCase();
30720
30803
  return p.name.toLowerCase().includes(q) || p.description && p.description.toLowerCase().includes(q);
30721
30804
  });
30722
- return /* @__PURE__ */ jsxs("div", { className: `flex-1 flex flex-col overflow-y-auto ${compact ? "p-3" : "p-6"}`, children: [
30723
- /* @__PURE__ */ jsxs("div", { className: `flex items-center justify-between ${compact ? "mb-3" : "mb-6"}`, children: [
30805
+ return /* @__PURE__ */ jsxs("div", { className: "flex-1 flex flex-col overflow-y-auto p-6", children: [
30806
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between mb-6", sidebarOffset && "ml-6"), children: [
30724
30807
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col min-w-0", children: [
30725
- /* @__PURE__ */ jsx("h1", { className: `font-semibold ps-2 truncate ${compact ? "text-base" : "text-2xl"}`, children: t("sections.projects") }),
30808
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-semibold ps-2 truncate", children: t("sections.projects") }),
30726
30809
  !compact && /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground ps-2", children: t("descriptions.manage_projects") })
30727
30810
  ] }),
30728
30811
  /* @__PURE__ */ jsxs(Button, { size: "sm", onClick: onNewProject, className: "shrink-0", children: [
@@ -30730,7 +30813,7 @@ var AssistantProjectsPanel = ({
30730
30813
  !compact && t("buttons.new_project")
30731
30814
  ] })
30732
30815
  ] }),
30733
- /* @__PURE__ */ jsx("div", { className: `flex items-center gap-4 ${compact ? "mb-3" : "mb-6"}`, children: /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
30816
+ /* @__PURE__ */ jsx("div", { className: "flex items-center gap-4 mb-6", children: /* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
30734
30817
  /* @__PURE__ */ jsx(Search, { className: "absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground w-4 h-4" }),
30735
30818
  /* @__PURE__ */ jsx(
30736
30819
  Input,
@@ -30957,11 +31040,13 @@ var SidebarContent = ({
30957
31040
  onShowMoreProjects,
30958
31041
  onNewProject,
30959
31042
  onToggleSidebar,
31043
+ supportWorkCanvas = true,
30960
31044
  t
30961
31045
  }) => {
30962
- const [activeListType, setActiveListType] = useState("sessions");
31046
+ const [storedListType, setActiveListType] = useState("sessions");
31047
+ const activeListType = !supportWorkCanvas && storedListType === "works" ? "sessions" : storedListType;
30963
31048
  const [openMenuId, setOpenMenuId] = useState(null);
30964
- const navItems = [{ id: 1, label: t("tabs.sessions"), icon: MessageSquare }, { id: 3, label: t("tabs.works"), icon: NotebookText }];
31049
+ const navItems = [{ id: 1, label: t("tabs.sessions"), icon: MessageSquare }, ...supportWorkCanvas ? [{ id: 3, label: t("tabs.works"), icon: NotebookText }] : []];
30965
31050
  return /* @__PURE__ */ jsxs("div", { className: "flex flex-col flex-1 min-h-0", children: [
30966
31051
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-px", children: [
30967
31052
  /* @__PURE__ */ jsx(
@@ -31033,7 +31118,7 @@ var SidebarContent = ({
31033
31118
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col mt-4 flex-1 min-h-0", children: [
31034
31119
  /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-start px-2 py-1.5 shrink-0", children: [
31035
31120
  /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-tight text-muted-foreground", children: t("sections.recents") }),
31036
- /* @__PURE__ */ jsxs(DropdownMenu$1, { children: [
31121
+ supportWorkCanvas ? /* @__PURE__ */ jsxs(DropdownMenu$1, { children: [
31037
31122
  /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
31038
31123
  Button,
31039
31124
  {
@@ -31076,7 +31161,7 @@ var SidebarContent = ({
31076
31161
  }
31077
31162
  )
31078
31163
  ] })
31079
- ] })
31164
+ ] }) : /* @__PURE__ */ jsx("span", { className: "ml-1 px-1 py-0 text-xs font-semibold uppercase tracking-tight text-muted-foreground", children: `${t("tabs.sessions")} (${sessions.length})` })
31080
31165
  ] }),
31081
31166
  /* @__PURE__ */ jsx(
31082
31167
  "div",
@@ -31425,6 +31510,9 @@ var DocyAssistant = ({
31425
31510
  };
31426
31511
  const [activeAgentId, setActiveAgentId] = useState(resolveInitialAgentId);
31427
31512
  const [deploymentId, setDeploymentId] = useState(resolveInitialDeploymentId);
31513
+ const isBaseAgent = !deploymentId && !!tenantAiAgentId;
31514
+ const { capabilities: agentCapabilities } = useDeploymentData(deploymentId || activeAgentId, supportMultiModels, isBaseAgent);
31515
+ const effectiveSupportWorkCanvas = agentCapabilities ? agentCapabilities.supportWorkCanvas : supportWorkCanvas;
31428
31516
  const title = titleProp || "DocyAssistant";
31429
31517
  const description = descriptionProp || t("descriptions.default");
31430
31518
  const placeholder = placeholderProp || t("placeholders.type_message");
@@ -31943,6 +32031,7 @@ var DocyAssistant = ({
31943
32031
  projectActions.setView("create");
31944
32032
  },
31945
32033
  onToggleSidebar: isFloating && !uiState.isExpanded ? () => uiActions.setSidebarOpen(false) : void 0,
32034
+ supportWorkCanvas: effectiveSupportWorkCanvas,
31946
32035
  t
31947
32036
  }
31948
32037
  );
@@ -32230,6 +32319,7 @@ var DocyAssistant = ({
32230
32319
  projectActions.setDeleteDialogOpen(true);
32231
32320
  },
32232
32321
  compact: enableNavDropdown,
32322
+ sidebarOffset: !uiState.isSidebarOpen && enableSidebar,
32233
32323
  t
32234
32324
  }
32235
32325
  ),