@ai-matrx/chat 0.2.5 → 0.2.7

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/agents/addressing/agentAddress.js +1 -1
  3. package/dist/agents/components/context-items/bodies/ProcessedDocumentTitle.js +3 -2
  4. package/dist/agents/components/context-items/bodies/WebpageBody.js +6 -1
  5. package/dist/agents/components/debug/SandboxFileViewer.js +6 -1
  6. package/dist/agents/components/debug/StreamDebugPanel.js +6 -1
  7. package/dist/agents/components/inputs/input-components/MediaVariableInput.js +1 -1
  8. package/dist/agents/components/inputs/resources/attached-documents.js +3 -2
  9. package/dist/agents/components/inputs/resources/usePasteImageResource.js +2 -2
  10. package/dist/agents/components/messages-display/TranscriptIntegrityCopyButton.js +6 -2
  11. package/dist/agents/components/observational-memory/components/MemoryStateInspector.d.ts +0 -12
  12. package/dist/agents/components/observational-memory/components/MemoryStateInspector.js +10 -2
  13. package/dist/agents/components/run-controls/AgentExecutionTestModal.js +6 -1
  14. package/dist/agents/components/shared/AgentDuplicateOutcomeDialog.d.ts +26 -2
  15. package/dist/agents/components/shared/AgentDuplicateOutcomeDialog.js +50 -4
  16. package/dist/agents/components/shared/AgentOptionsMenu.js +11 -61
  17. package/dist/agents/components/shared/StreamProfilerOverlay.js +6 -1
  18. package/dist/agents/hooks/useAgentDuplicateFlow.d.ts +13 -3
  19. package/dist/agents/hooks/useAgentDuplicateFlow.js +81 -24
  20. package/dist/agents/hooks/useWidgetHandle.js +1 -1
  21. package/dist/agents/prompt-preview/PromptPreviewContent.js +6 -1
  22. package/dist/agents/redux/agent-definition/cache-bust-middleware.js +1 -1
  23. package/dist/agents/redux/agent-definition/parse-messages-variables.js +6 -0
  24. package/dist/agents/redux/agent-shortcuts/thunks.js +1 -1
  25. package/dist/agents/redux/execution-system/instance-resources/resource-source.js +1 -2
  26. package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +1 -1
  27. package/dist/agents/redux/execution-system/thunks/launch-conversation.thunk.js +1 -1
  28. package/dist/agents/redux/execution-system/utils/assert-conversation-id.js +1 -1
  29. package/dist/agents/redux/execution-system/utils/content-prefilter.js +2 -2
  30. package/dist/agents/runtime/realtime/launchRealtimeSession.thunk.js +1 -1
  31. package/dist/agents/surface-catalog-profile.d.ts +1 -1
  32. package/dist/agents/types/agent-definition.types.d.ts +8 -6
  33. package/dist/agents/utils/variable-customcomponent.d.ts +2 -2
  34. package/dist/agents/utils/variable-customcomponent.js +4 -4
  35. package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
  36. package/dist/cx-chat/components/user-input/ConversationInput.js +1 -1
  37. package/dist/cx-conversation/AssistantMessage.js +1 -1
  38. package/dist/cx-conversation/ConversationInput.js +1 -1
  39. package/dist/host/builder-door.d.ts +13 -2
  40. package/dist/host/db-types.d.ts +4 -4
  41. package/dist/host/defaults/diagnostics.js +1 -1
  42. package/dist/host/ui-slots.d.ts +0 -20
  43. package/dist/host/ui-slots.js +0 -26
  44. package/dist/store/create-chat-store.d.ts +2 -0
  45. package/dist/store/create-chat-store.js +15 -3
  46. package/dist/surfaces/runtime/loaded-value-check.js +1 -1
  47. package/dist/surfaces/runtime/surface-writeback.js +1 -1
  48. package/dist/surfaces/utils/route-to-surface.js +1 -1
  49. package/dist/surfaces/utils/surface-display.js +1 -1
  50. package/dist/tool-call-visualization/result-fields/shape.js +1 -1
  51. package/dist/ui/file-source.d.ts +3 -17
  52. package/dist/voice-agent/components/VoiceDebugPanel.js +6 -1
  53. package/dist/voice-agent/hooks/useRealtimeAgentConfig.js +1 -1
  54. package/dist/voice-agent/hooks/useXaiVoiceSession.js +2 -2
  55. package/dist/voice-agent/transport/xaiClient.js +1 -1
  56. package/dist/window-panels/windows/agents/AgentMemoryWindow.js +7 -5
  57. package/package.json +3 -3
@@ -5,8 +5,10 @@ import { usePathname } from "../../host/navigation.js";
5
5
  import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
6
6
  import { selectAgentById } from "../redux/agent-definition/selectors.js";
7
7
  import { getBuilderDoor, requireBuilderDoor } from "../../host/builder-door.js";
8
+ import { supabase } from "../../host/db.js";
8
9
  import {
9
- AgentDuplicateOutcomeDialog
10
+ AgentDuplicateOutcomeDialog,
11
+ CURRENT_VERSION_CHOICE
10
12
  } from "../components/shared/AgentDuplicateOutcomeDialog.js";
11
13
  import { isAdminSystemAgentsContext } from "../components/shared/agent-route-context.js";
12
14
  import { getUserMessage } from "@ai-matrx/agents/matrx";
@@ -15,56 +17,111 @@ function useAgentDuplicateFlow(agentId, options) {
15
17
  const dispatch = useAppDispatch();
16
18
  const pathname = usePathname();
17
19
  const basePath = options?.basePath ?? "/agents";
20
+ const fallbackSuffix = options?.fallbackSuffix ?? "/build";
18
21
  const agent = useAppSelector((state2) => selectAgentById(state2, agentId));
19
22
  const [open, setOpen] = useState(false);
20
23
  const [state, setState] = useState("loading");
21
24
  const [newAgentId, setNewAgentId] = useState(null);
22
25
  const [errorMessage, setErrorMessage] = useState("");
23
26
  const [asSystem, setAsSystem] = useState(false);
27
+ const [versions, setVersions] = useState([]);
28
+ const [versionsLoading, setVersionsLoading] = useState(false);
29
+ const [versionsError, setVersionsError] = useState(null);
30
+ const [selected, setSelected] = useState(CURRENT_VERSION_CHOICE);
31
+ const newAgent = useAppSelector(
32
+ (s) => newAgentId ? selectAgentById(s, newAgentId) : void 0
33
+ );
24
34
  const isAdminContext = isAdminSystemAgentsContext(basePath);
25
35
  const isBuiltin = agent?.agentType === "builtin";
26
- const newAgentName = agent?.name ? `Copy of ${agent.name}` : "";
27
36
  const newAgentPath = newAgentId ? (() => {
28
37
  const sourceSegment = `${basePath}/${agentId}`;
29
- const suffix = pathname && pathname.startsWith(sourceSegment) ? pathname.slice(sourceSegment.length) : "/build";
30
- return `${basePath}/${newAgentId}${suffix || "/build"}`;
38
+ const here = pathname && pathname.startsWith(sourceSegment) ? pathname.slice(sourceSegment.length) : fallbackSuffix;
39
+ const suffix = /^\/v(\/|$)/.test(here) ? fallbackSuffix : here;
40
+ return `${basePath}/${newAgentId}${suffix || fallbackSuffix}`;
31
41
  })() : null;
32
- const startDuplicate = useCallback(async () => {
33
- const duplicateAsSystem = isAdminContext && isBuiltin;
34
- setAsSystem(duplicateAsSystem);
42
+ const startDuplicate = useCallback(
43
+ async (opts) => {
44
+ const duplicateAsSystem = isAdminContext && isBuiltin;
45
+ setAsSystem(duplicateAsSystem);
46
+ setNewAgentId(null);
47
+ setErrorMessage("");
48
+ setState("loading");
49
+ setOpen(true);
50
+ try {
51
+ const id = await dispatch(
52
+ requireBuilderDoor().duplicateAgent({
53
+ agentId,
54
+ asSystem: duplicateAsSystem,
55
+ versionId: opts?.versionId
56
+ })
57
+ ).unwrap();
58
+ setNewAgentId(id);
59
+ setState("success");
60
+ } catch (err) {
61
+ if (isOrganizationSelectionCancelled(err)) {
62
+ setOpen(false);
63
+ return;
64
+ }
65
+ setErrorMessage(getUserMessage(err));
66
+ setState("error");
67
+ }
68
+ },
69
+ [agentId, dispatch, isAdminContext, isBuiltin]
70
+ );
71
+ const openChooser = useCallback(async () => {
72
+ setSelected(CURRENT_VERSION_CHOICE);
35
73
  setNewAgentId(null);
36
74
  setErrorMessage("");
37
- setState("loading");
75
+ setState("choose");
38
76
  setOpen(true);
39
- try {
40
- const id = await dispatch(
41
- requireBuilderDoor().duplicateAgent({ agentId, asSystem: duplicateAsSystem })
42
- ).unwrap();
43
- setNewAgentId(id);
44
- setState("success");
45
- } catch (err) {
46
- if (isOrganizationSelectionCancelled(err)) {
47
- setOpen(false);
48
- return;
49
- }
50
- setErrorMessage(getUserMessage(err));
51
- setState("error");
77
+ setVersionsLoading(true);
78
+ setVersionsError(null);
79
+ const { data, error } = await supabase.rpc("agx_get_version_history", {
80
+ p_agent_id: agentId,
81
+ p_limit: 500,
82
+ p_offset: 0
83
+ });
84
+ setVersionsLoading(false);
85
+ if (error) {
86
+ setVersions([]);
87
+ setVersionsError(error.message);
88
+ return;
52
89
  }
53
- }, [agentId, dispatch, isAdminContext, isBuiltin]);
90
+ setVersions(
91
+ (data ?? []).map((row) => ({
92
+ versionId: row.version_id,
93
+ versionNumber: row.version_number,
94
+ changedAt: row.changed_at,
95
+ changeNote: row.change_note ?? null
96
+ }))
97
+ );
98
+ }, [agentId]);
54
99
  const dialog = /* @__PURE__ */ jsx(
55
100
  AgentDuplicateOutcomeDialog,
56
101
  {
57
102
  open,
58
103
  onOpenChange: setOpen,
59
104
  state,
60
- newAgentName,
105
+ newAgentName: newAgent?.name ?? "",
61
106
  newAgentPath,
62
107
  errorMessage,
63
- asSystem
108
+ asSystem,
109
+ chooser: {
110
+ currentVersion: agent?.version ?? null,
111
+ versions,
112
+ versionsLoading,
113
+ versionsError,
114
+ selected,
115
+ onSelectedChange: setSelected,
116
+ onConfirm: () => void startDuplicate(
117
+ selected === CURRENT_VERSION_CHOICE ? void 0 : { versionId: selected }
118
+ )
119
+ }
64
120
  }
65
121
  );
66
122
  return {
67
123
  startDuplicate,
124
+ openChooser,
68
125
  dialog,
69
126
  isDuplicating: open && state === "loading",
70
127
  /** False in a host that registered no builder door: nothing offers a duplicate (reported once). */
@@ -38,7 +38,7 @@ function useWidgetHandle(handle) {
38
38
  idRef.current = callbackManager.registerWidgetHandle(
39
39
  makeStableHandle(handleRef)
40
40
  );
41
- if (true) {
41
+ if (process.env.NODE_ENV !== "production") {
42
42
  const methodCount = [
43
43
  ...Object.values(WIDGET_TOOL_NAME_TO_HANDLE_METHOD),
44
44
  ...LIFECYCLE_KEYS
@@ -1,5 +1,7 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useClipboard } from "@ai-matrx/kit/clipboard";
4
+ import { toast as copyToast } from "../../host/notify.js";
3
5
  import { useEffect, useState } from "react";
4
6
  import { Loader2, Copy, RefreshCw, AlertTriangle } from "lucide-react";
5
7
  import { Button } from "@ai-matrx/design-system/controls";
@@ -10,6 +12,9 @@ import { ErrorAlchemyMenu } from "../../host/ui-slots.js";
10
12
  function PromptPreviewContent({
11
13
  conversationId
12
14
  }) {
15
+ const { copyText } = useClipboard({
16
+ notify: (message, kind) => kind === "error" ? copyToast.error(message) : copyToast.success(message)
17
+ });
13
18
  const store = useAppStore();
14
19
  const [loading, setLoading] = useState(false);
15
20
  const [error, setError] = useState(null);
@@ -39,7 +44,7 @@ function PromptPreviewContent({
39
44
  }, [conversationId, store, nonce]);
40
45
  const copy = async (label, text) => {
41
46
  try {
42
- await navigator.clipboard.writeText(text);
47
+ await copyText(text);
43
48
  toast.success(`${label} copied`);
44
49
  } catch {
45
50
  toast.error("Couldn't copy");
@@ -43,7 +43,7 @@ async function bustAgentCache(baseUrl, agentId, headers) {
43
43
  keepalive: true
44
44
  });
45
45
  } catch (err) {
46
- if (true) {
46
+ if (process.env.NODE_ENV !== "production") {
47
47
  console.warn(`[agent cache-bust] ${agentId} \u2192`, err);
48
48
  }
49
49
  }
@@ -28,6 +28,7 @@ const VARIABLE_COMPONENT_KNOWN_KEYS = [
28
28
  "min",
29
29
  "max",
30
30
  "step",
31
+ "pick_list",
31
32
  "structured_list",
32
33
  "picklist",
33
34
  "assignment",
@@ -201,6 +202,10 @@ function parseVariableCustomComponent(value, path) {
201
202
  const min = parseOptionalNumber(value.min, `${path}.min`);
202
203
  const max = parseOptionalNumber(value.max, `${path}.max`);
203
204
  const step = parseOptionalNumber(value.step, `${path}.step`);
205
+ const pickList = parseStructuredListBinding(
206
+ value.pick_list,
207
+ `${path}.pick_list`
208
+ );
204
209
  const structuredList = parseStructuredListBinding(
205
210
  value.structured_list,
206
211
  `${path}.structured_list`
@@ -224,6 +229,7 @@ function parseVariableCustomComponent(value, path) {
224
229
  if (min !== void 0) parsed.min = min;
225
230
  if (max !== void 0) parsed.max = max;
226
231
  if (step !== void 0) parsed.step = step;
232
+ if (pickList !== void 0) parsed.pick_list = pickList;
227
233
  if (structuredList !== void 0) parsed.structured_list = structuredList;
228
234
  if (picklist !== void 0) parsed.picklist = picklist;
229
235
  if (assignment !== void 0) parsed.assignment = assignment;
@@ -708,7 +708,7 @@ const fetchUnifiedMenu = createAsyncThunk(
708
708
  const categoryDefs = [];
709
709
  const shortcutDefs = [];
710
710
  const contentBlockDefs = [];
711
- if (true) {
711
+ if (process.env.NODE_ENV !== "production") {
712
712
  const placementSummary = (payload.data ?? []).map((p) => ({
713
713
  placement_type: p.placement_type,
714
714
  categories: (p.categories_flat ?? []).length,
@@ -1,5 +1,4 @@
1
- import { normalize } from "../../../../host/ui-slots.js";
2
- import { toMediaRef } from "../../../../host/ui-slots.js";
1
+ import { normalize, toMediaRef } from "@ai-matrx/media/files/engine";
3
2
  const MEDIA_BLOCK_TYPES = /* @__PURE__ */ new Set([
4
3
  "image",
5
4
  "audio",
@@ -532,7 +532,7 @@ const executeManualInstance = createAsyncThunk(
532
532
  })
533
533
  );
534
534
  }
535
- if (true) {
535
+ if (process.env.NODE_ENV !== "production") {
536
536
  if (/\/ai\/agents\//.test(url) || /\/ai\/conversations\//.test(url)) {
537
537
  throw new Error(
538
538
  `[ManualExec] Forbidden URL "${url}". The manual execution path must NEVER hit /ai/agents/* or /ai/conversations/* (those do server-side definition lookup + caching). Use /ai/manual or a deliberate route override via manualEndpointOverride / apiConfig.`
@@ -61,7 +61,7 @@ function invocationToManagedOptions(invocation) {
61
61
  return managed;
62
62
  }
63
63
  function warnUnsupported(invocation) {
64
- if (false) return;
64
+ if (process.env.NODE_ENV === "production") return;
65
65
  if (invocation.identity.conversationId) {
66
66
  console.warn(
67
67
  "[launchConversation] identity.conversationId is passed through to the execution thunk, but turn-2+ routing currently still goes through executeInstance's existing `selectHasMessages` branch. The explicit conversationId-in-invocation path lands in Phase 3."
@@ -2,7 +2,7 @@ function assertConversationIdMatches(localConversationId, incomingId, source) {
2
2
  if (!incomingId) return;
3
3
  if (incomingId === localConversationId) return;
4
4
  const message = `[conversation-id drift] server returned a different conversation id via ${source}. local=${localConversationId} incoming=${incomingId}. The server must honor the client-generated conversation id.`;
5
- if (true) {
5
+ if (process.env.NODE_ENV !== "production") {
6
6
  throw new Error(message);
7
7
  }
8
8
  console.error(message);
@@ -1,4 +1,4 @@
1
- import { ourFileUrlMarkers } from "../../../../host/ui-slots.js";
1
+ import { OUR_FILE_URL_MARKERS } from "@ai-matrx/media/files/engine";
2
2
  const Candidate = {
3
3
  NONE: 0,
4
4
  TEXT: 0,
@@ -34,7 +34,7 @@ function isStandaloneAudioLink(trimmed) {
34
34
  return false;
35
35
  }
36
36
  function mightBeOurFile(trimmed) {
37
- const markers = ourFileUrlMarkers();
37
+ const markers = OUR_FILE_URL_MARKERS;
38
38
  for (let mi = 0; mi < markers.length; mi++) {
39
39
  if (trimmed.includes(markers[mi])) return true;
40
40
  }
@@ -2,7 +2,7 @@ import { createAsyncThunk } from "@reduxjs/toolkit";
2
2
  const launchRealtimeSession = createAsyncThunk("agents/runtime/launchRealtimeSession", async (opts) => {
3
3
  const { agentId, surfaceName } = opts;
4
4
  const instanceId = `realtime-${agentId}`;
5
- if (true) {
5
+ if (process.env.NODE_ENV !== "production") {
6
6
  console.debug(
7
7
  "[launchRealtimeSession] resolved",
8
8
  { agentId, surfaceName, instanceId }
@@ -16,7 +16,7 @@
16
16
  * `settings_catalog_profile`.
17
17
  *
18
18
  * Two target definitions over the same fields is a defect, not a coincidence:
19
- * the campaign's own precedent is `matrx-user/lists` / `matrx-user/list-manager`,
19
+ * the campaign's own precedent is `matrx-user/pick-lists` / `matrx-user/pick-list-manager`,
20
20
  * whose shared targets were lifted into `features/data-tables/pick-lists/`. So the CONTRACT
21
21
  * — the accepted keys, the per-field bounds, the replace-vs-patch semantics,
22
22
  * and the model-facing prose that states them — is defined exactly once, here.
@@ -26,7 +26,7 @@ export type VariableComponentType = (typeof VARIABLE_COMPONENT_TYPES)[number];
26
26
  * Binding of a variable to a Structured List (a Table of choices in the record store). When set, the
27
27
  * variable's options are hydrated at runtime from the list (labels only — the secret `description`
28
28
  * never reaches the client) and the emitted value is a ```matrx reference fence string
29
- * (`kind:"reference"`, `type:"structured_list_item"`), not text. Orthogonal to `type`, so a
29
+ * (`kind:"reference"`, `type:"pick_list_item"`), not text. Orthogonal to `type`, so a
30
30
  * structured-list-bound variable can render as select / radio / buttons / checkbox (a "picklist"
31
31
  * in the dropdown-projection sense).
32
32
  */
@@ -69,16 +69,18 @@ export interface VariableCustomComponent {
69
69
  unit?: string;
70
70
  /**
71
71
  * Structured-list binding. When present, options come from the bound Structured List and the
72
- * variable's value is a ```matrx reference fence string (one `structured_list_item` for
72
+ * variable's value is a ```matrx reference fence string (one `pick_list_item` for
73
73
  * single-select, N items + any "Other" lines for multi). Kept top-level (not stashable) so it
74
74
  * survives component-type switches.
75
75
  */
76
- structured_list?: StructuredListBinding;
76
+ pick_list?: StructuredListBinding;
77
77
  /**
78
- * @deprecated Legacy key — READ-ONLY. Historical agent definitions store the binding under
79
- * `picklist`; readers fall back to it via {@link readStructuredList}. New writes use
80
- * `structured_list` only. Do not emit this key.
78
+ * @deprecated Legacy keys — READ-ONLY. Historical agent definitions store the binding under
79
+ * `structured_list` or `picklist`; readers fall back to them via {@link readStructuredList}.
80
+ * New writes use `pick_list` only. Do not emit these keys.
81
81
  */
82
+ structured_list?: StructuredListBinding;
83
+ /** @deprecated Legacy key — READ-ONLY (see `structured_list`). */
82
84
  picklist?: StructuredListBinding;
83
85
  /** Automatic-assignment strategies explicitly enabled by the agent author. */
84
86
  assignment?: VariableAssignmentConfig;
@@ -21,8 +21,8 @@ export declare function readMax(cc: VariableCustomComponent | undefined): number
21
21
  export declare function readStep(cc: VariableCustomComponent | undefined): number;
22
22
  /**
23
23
  * The structured-list binding, if this variable is bound to a Structured List. Top-level only.
24
- * Reads the canonical `structured_list` key and falls back to the legacy `picklist` key
25
- * (read-only back-compat for historical agent definitions — new writes use `structured_list`).
24
+ * Reads the canonical `pick_list` key and falls back to the legacy `structured_list` and `picklist` keys
25
+ * (read-only back-compat for historical agent definitions — new writes use `pick_list`).
26
26
  */
27
27
  export declare function readStructuredList(cc: VariableCustomComponent | undefined): StructuredListBinding | undefined;
28
28
  export interface BuildCustomComponentInput {
@@ -48,7 +48,7 @@ function readStep(cc) {
48
48
  return cc?.step ?? cc?.stash?.step ?? 1;
49
49
  }
50
50
  function readStructuredList(cc) {
51
- return cc?.structured_list ?? cc?.picklist;
51
+ return cc?.pick_list ?? cc?.structured_list ?? cc?.picklist;
52
52
  }
53
53
  function buildCustomComponent(input) {
54
54
  const { type } = input;
@@ -81,7 +81,7 @@ function buildCustomComponent(input) {
81
81
  cc.stash = stash;
82
82
  }
83
83
  if (input.structuredList?.listId) {
84
- cc.structured_list = input.structuredList;
84
+ cc.pick_list = input.structuredList;
85
85
  }
86
86
  if (input.randomAssignment) {
87
87
  cc.assignment = { random: true };
@@ -89,7 +89,7 @@ function buildCustomComponent(input) {
89
89
  if (input.resourceContext && ((input.resourceContext.promote?.length ?? 0) > 0 || (input.resourceContext.exclude?.length ?? 0) > 0)) {
90
90
  cc.resource_context = input.resourceContext;
91
91
  }
92
- if (type === "textarea" && !cc.stash && !cc.structured_list && !cc.assignment && !cc.resource_context)
92
+ if (type === "textarea" && !cc.stash && !cc.pick_list && !cc.assignment && !cc.resource_context)
93
93
  return void 0;
94
94
  return cc;
95
95
  }
@@ -114,7 +114,7 @@ function normalizeCustomComponent(cc) {
114
114
  const { stash: _drop, ...rest } = next;
115
115
  next = rest;
116
116
  }
117
- if (next.type === "textarea" && !next.stash && !next.structured_list && !next.picklist && !next.assignment && !next.resource_context)
117
+ if (next.type === "textarea" && !next.stash && !next.pick_list && !next.structured_list && !next.picklist && !next.assignment && !next.resource_context)
118
118
  return void 0;
119
119
  return next;
120
120
  }
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { recognizeOurFileUrl } from "@ai-matrx/media/files/engine";
3
4
  import { useState, useEffect, useCallback } from "react";
4
5
  import {
5
6
  Volume2,
@@ -17,7 +18,6 @@ import { selectMessageHasUnsavedChanges } from "../../_legacy-stubs.js";
17
18
  import { editMessage } from "../../_legacy-stubs.js";
18
19
  import { buildContentBlocksForSave } from "../../utils/buildContentBlocksForSave.js";
19
20
  import { useMediaLoadRecovery } from "@ai-matrx/media/core";
20
- import { recognizeOurFileUrl } from "../../../host/ui-slots.js";
21
21
  import { chatConversationsActions } from "../../_legacy-stubs.js";
22
22
  import { RichDocumentActions } from "../../../host/rich-document-slots.js";
23
23
  import { MessageTimestamp } from "../../../agents/components/messages-display/MessageTimestamp.js";
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useFileUpload } from "@ai-matrx/media/files/engine/handler/hooks/useFileUpload";
3
4
  import {
4
5
  useState,
5
6
  useRef,
@@ -44,7 +45,6 @@ import { selectIsDebugMode } from "../../../host/prefs.js";
44
45
  import { openOverlay, CHAT_WINDOWS } from "../../../host/windows.js";
45
46
  import { ResourceChips } from "../../../agents/resources/ResourceChips.js";
46
47
  import { useClipboardPaste } from "../../../host/ui-slots.js";
47
- import { useFileUpload } from "../../../host/ui-slots.js";
48
48
  import { composeUploadFolderPath } from "@ai-matrx/media/files";
49
49
  import { RunControlsMenu } from "../../../agents/components/inputs/smart-input/RunControlsMenu.js";
50
50
  import { PlusAttachMenu } from "../../../agents/components/inputs/smart-input/PlusAttachMenu.js";
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { recognizeOurFileUrl } from "@ai-matrx/media/files/engine";
3
4
  import { useState, useEffect, useCallback } from "react";
4
5
  import {
5
6
  Volume2,
@@ -17,7 +18,6 @@ import { selectMessageHasUnsavedChanges } from "./_legacy-stubs.js";
17
18
  import { editMessage } from "./_legacy-stubs.js";
18
19
  import { buildContentBlocksForSave } from "./utils/buildContentBlocksForSave.js";
19
20
  import { useMediaLoadRecovery } from "@ai-matrx/media/core";
20
- import { recognizeOurFileUrl } from "../host/ui-slots.js";
21
21
  import { chatConversationsActions } from "./_legacy-stubs.js";
22
22
  import { RichDocumentActions } from "../host/rich-document-slots.js";
23
23
  import { MessageTimestamp } from "../agents/components/messages-display/MessageTimestamp.js";
@@ -1,5 +1,6 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useFileUpload } from "@ai-matrx/media/files/engine/handler/hooks/useFileUpload";
3
4
  import {
4
5
  useState,
5
6
  useRef,
@@ -54,7 +55,6 @@ import { selectActiveChatAgent } from "./_legacy-stubs.js";
54
55
  import { selectIsDebugMode } from "../host/prefs.js";
55
56
  import { ResourceChips } from "../agents/resources/ResourceChips.js";
56
57
  import { ResourcePickerMenu } from "../host/ui-slots.js";
57
- import { useFileUpload } from "../host/ui-slots.js";
58
58
  import { composeUploadFolderPath } from "@ai-matrx/media/files";
59
59
  import { useRecordAndTranscribe } from "../host/ui-slots.js";
60
60
  import { TranscriptionLoader } from "../host/ui-slots.js";
@@ -17,12 +17,23 @@ type Cfg = {
17
17
  state: ChatRootState;
18
18
  };
19
19
  type Door<Arg, Ret> = (arg: Arg) => AsyncThunkAction<Ret, Arg, Cfg>;
20
- export interface DuplicateAgentOptions {
21
- agentId: string;
20
+ interface DuplicateAgentCommon {
22
21
  asSystem?: boolean;
23
22
  organizationId?: string;
24
23
  followsSource?: boolean;
25
24
  }
25
+ /**
26
+ * What to copy into a new agent: the agent as it is now (`agentId`), or one
27
+ * exact saved version (`versionId`, an agent.definition_version id — its
28
+ * snapshot is copied, never the possibly-newer master).
29
+ */
30
+ export type DuplicateAgentOptions = DuplicateAgentCommon & ({
31
+ agentId: string;
32
+ versionId?: string;
33
+ } | {
34
+ agentId?: string;
35
+ versionId: string;
36
+ });
26
37
  export type CreateAgentInput = Partial<Omit<AgentDefinition, "id" | "createdBy" | "createdAt" | "updatedAt" | "isVersion" | "parentAgentId" | "version" | "changedAt" | "changeNote">>;
27
38
  export interface BuilderDoor {
28
39
  saveAgent: Door<string, void>;
@@ -32136,7 +32136,7 @@ export type ChatDatabase = {
32136
32136
  isSetofReturn: true;
32137
32137
  };
32138
32138
  };
32139
- _d31_impl_get_pick_list_with_items: {
32139
+ _d31_impl_get_user_list_with_items: {
32140
32140
  Args: {
32141
32141
  p_list_id: string;
32142
32142
  };
@@ -32180,7 +32180,7 @@ export type ChatDatabase = {
32180
32180
  };
32181
32181
  Returns: Json;
32182
32182
  };
32183
- _d31_impl_update_pick_list: {
32183
+ _d31_impl_update_user_list: {
32184
32184
  Args: {
32185
32185
  p_authenticated_read?: boolean;
32186
32186
  p_description?: string;
@@ -38689,7 +38689,7 @@ export type ChatDatabase = {
38689
38689
  };
38690
38690
  Returns: Json;
38691
38691
  };
38692
- get_pick_list_with_items: {
38692
+ get_user_list_with_items: {
38693
38693
  Args: {
38694
38694
  p_list_id: string;
38695
38695
  };
@@ -43920,7 +43920,7 @@ export type ChatDatabase = {
43920
43920
  };
43921
43921
  Returns: Json;
43922
43922
  };
43923
- update_pick_list: {
43923
+ update_user_list: {
43924
43924
  Args: {
43925
43925
  p_authenticated_read?: boolean;
43926
43926
  p_description?: string;
@@ -32,7 +32,7 @@ function currentRoute() {
32
32
  }
33
33
  }
34
34
  function createLogClientErrorDiagnostics(db, options) {
35
- const persist = options.persist ?? false;
35
+ const persist = options.persist ?? process.env.NODE_ENV === "production";
36
36
  const flushDelayMs = options.flushDelayMs ?? DIAGNOSTICS_FLUSH_DELAY_MS;
37
37
  const sourceApp = isChatSourceApp(options.sourceApp) ? options.sourceApp : null;
38
38
  const persisted = /* @__PURE__ */ new Set();
@@ -231,19 +231,11 @@ export interface ChatUiSlots {
231
231
  ChangeDiff: AnyComponent;
232
232
  SearchGroup: AnyComponent;
233
233
  SearchGroupTrigger: AnyComponent;
234
- /** The host's upload hook: `{ upload, uploadMany, uploading, progress, result, error, reset }`. */
235
- useFileUpload: AnyFn;
236
- /** One file from the host's file store by source: `{ file }`. */
237
- useFile: AnyFn;
238
234
  useFileDocument: AnyFn;
239
235
  useFileResourceFamily: AnyFn;
240
236
  useFileActions: AnyFn;
241
237
  /** The host's record-then-transcribe hook (`isRecording`, `startRecording`, ...). */
242
238
  useRecordAndTranscribe: AnyFn;
243
- /** Resolves a file source to its stored file (the host's file handler). */
244
- resolveFile: AnyFn;
245
- /** The host's rename-file thunk creator (`dispatch(renameFile({ fileId, newName })).unwrap()`). */
246
- renameFile: AnyFn;
247
239
  requestScribeAudioSeek: AnyFn;
248
240
  resolvePdfSurfaceIds: AnyFn;
249
241
  /** The host's list RPC reader (`{ data, error }`). */
@@ -326,13 +318,11 @@ export interface ChatUiSlots {
326
318
  dispatchWarRoomMasterTool: AnyFn;
327
319
  resolveGmailSendConnection: AnyFn;
328
320
  voiceDisplayName: AnyFn;
329
- recognizeOurFileUrl: AnyFn;
330
321
  canvasGetVersionHistory: (canvasId: string) => Promise<CanvasItemRow[]>;
331
322
  canvasGetById: (canvasId: string) => Promise<CanvasItemRow | null>;
332
323
  createSandboxFilesystemAdapter: AnyFn;
333
324
  notesGetById: AnyFn;
334
325
  isLiveConversationVoice: AnyFn;
335
- ourFileUrlMarkers: AnyFn;
336
326
  createHtmlPage: AnyFn;
337
327
  convertMarkdownToHtml: AnyFn;
338
328
  sklActions: Record<string, AnyFn>;
@@ -391,8 +381,6 @@ export interface ChatUiSlots {
391
381
  pushAppHref: AnyFn;
392
382
  replaceAppHref: AnyFn;
393
383
  announceComingSoon: AnyFn;
394
- normalize: AnyFn;
395
- toMediaRef: AnyFn;
396
384
  peekSystemOrgId: AnyFn;
397
385
  toGlobalOwnershipRecord: AnyFn;
398
386
  fromGlobalOwnershipRecord: AnyFn;
@@ -601,14 +589,10 @@ export declare const ChangeDiff: AnyComponent;
601
589
  /** A host with no search toolbar lays the group's buttons out in a plain row. */
602
590
  export declare const SearchGroup: AnyComponent;
603
591
  export declare const SearchGroupTrigger: AnyComponent;
604
- export declare const useFileUpload: AnyFn;
605
- export declare const useFile: AnyFn;
606
592
  export declare const useFileDocument: AnyFn;
607
593
  export declare const useFileResourceFamily: AnyFn;
608
594
  export declare const useFileActions: AnyFn;
609
595
  export declare const useRecordAndTranscribe: AnyFn;
610
- export declare const resolveFile: AnyFn;
611
- export declare const renameFile: AnyFn;
612
596
  /** A host with no transcript studio has no audio to seek; the request is a reported no-op. */
613
597
  export declare const requestScribeAudioSeek: AnyFn;
614
598
  export declare const resolvePdfSurfaceIds: AnyFn;
@@ -729,13 +713,11 @@ export declare const dispatchWarRoomTool: AnyFn;
729
713
  export declare const dispatchWarRoomMasterTool: AnyFn;
730
714
  export declare const resolveGmailSendConnection: AnyFn;
731
715
  export declare const voiceDisplayName: AnyFn;
732
- export declare const recognizeOurFileUrl: AnyFn;
733
716
  export declare const canvasGetVersionHistory: (canvasId: string) => Promise<CanvasItemRow[]>;
734
717
  export declare const canvasGetById: (canvasId: string) => Promise<CanvasItemRow | null>;
735
718
  export declare const createSandboxFilesystemAdapter: AnyFn;
736
719
  export declare const notesGetById: AnyFn;
737
720
  export declare const isLiveConversationVoice: AnyFn;
738
- export declare const ourFileUrlMarkers: AnyFn;
739
721
  export declare const createHtmlPage: AnyFn;
740
722
  export declare const convertMarkdownToHtml: AnyFn;
741
723
  /** The host's skill-library action creators (`sklActions.x(...)`); resolved at call time, a bare host throws naming the slot. */
@@ -754,8 +736,6 @@ export declare const readOf: AnyFn;
754
736
  export declare const pushAppHref: AnyFn;
755
737
  export declare const replaceAppHref: AnyFn;
756
738
  export declare const announceComingSoon: AnyFn;
757
- export declare const normalize: AnyFn;
758
- export declare const toMediaRef: AnyFn;
759
739
  export declare const peekSystemOrgId: AnyFn;
760
740
  export declare const toGlobalOwnershipRecord: AnyFn;
761
741
  export declare const fromGlobalOwnershipRecord: AnyFn;