@ai-matrx/chat 0.2.9 → 0.3.2
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/CHANGELOG.md +34 -0
- package/dist/agent-copy/clipboard.d.ts +2 -4
- package/dist/agent-copy/clipboard.js +1 -14
- package/dist/agent-copy/page-capture/pageCapture.d.ts +11 -62
- package/dist/agent-copy/page-capture/pageCapture.js +5 -22
- package/dist/agents/components/context-items/bodies/WebpageBody.js +1 -1
- package/dist/agents/components/context-preview/AttachedContextSection.js +9 -8
- package/dist/agents/components/context-preview/ContextCompareView.js +13 -13
- package/dist/agents/components/context-preview/ContextPreviewPanel.js +13 -13
- package/dist/agents/components/conversation-actions/conversation-verbs.js +2 -6
- package/dist/agents/components/debug/SandboxFileViewer.js +1 -1
- package/dist/agents/components/debug/StreamDebugPanel.js +2 -2
- package/dist/agents/components/messages-display/TranscriptIntegrityCopyButton.js +1 -1
- package/dist/agents/components/observational-memory/components/MemoryStateInspector.js +4 -4
- package/dist/agents/components/run-controls/AgentExecutionTestModal.js +2 -2
- package/dist/agents/components/run-controls/PayloadTab.js +7 -1
- package/dist/agents/components/run-controls/panels/BackendTargetPanel.js +7 -1
- package/dist/agents/components/shared/AgentSaveStatus.js +22 -1
- package/dist/agents/hooks/useAgentAutoSave.js +14 -2
- package/dist/agents/menu/agent-actions.js +3 -5
- package/dist/agents/prompt-preview/PromptPreviewContent.js +1 -1
- package/dist/agents/redux/agent-definition/slice.js +1 -0
- package/dist/agents/redux/agent-settings/agentSettingsSlice.d.ts +3 -0
- package/dist/agents/redux/agent-settings/agentSettingsSlice.js +12 -2
- package/dist/agents/redux/agent-settings/types.d.ts +7 -0
- package/dist/agents/redux/agent-shortcuts/thunks.js +9 -5
- package/dist/agents/redux/execution-system/instance-resources/remarks.d.ts +6 -0
- package/dist/agents/redux/execution-system/instance-resources/remarks.js +16 -0
- package/dist/agents/redux/execution-system/instance-ui-state/components/InstanceUIStateCore.js +7 -1
- package/dist/agents/redux/execution-system/instance-ui-state/components/InstanceUIStateList.js +7 -1
- package/dist/agents/redux/execution-system/message-crud/commit-inline-edit.thunk.js +2 -1
- package/dist/canvas/workspace/useCanvasWorkspaceConversation.d.ts +12 -0
- package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +29 -1
- package/dist/context-menu/types.d.ts +7 -0
- package/dist/cx-chat/components/messages/AssistantMessage.js +8 -10
- package/dist/cx-chat/components/messages/UserMessage.js +7 -1
- package/dist/cx-conversation/AssistantMessage.js +8 -10
- package/dist/cx-conversation/UserMessage.js +7 -1
- package/dist/host/clipboard.d.ts +7 -0
- package/dist/host/clipboard.js +11 -0
- package/dist/host/db-types.d.ts +15 -12
- package/dist/host/ui-slots.d.ts +2 -8
- package/dist/host/ui-slots.js +11 -16
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +9 -16
- package/dist/store/create-chat-store.d.ts +10 -1
- package/dist/store/create-chat-store.js +4 -2
- package/dist/surfaces/runtime/SurfaceRuntimeContext.d.ts +10 -0
- package/dist/surfaces/runtime/SurfaceRuntimeContext.js +23 -1
- package/dist/surfaces/services/surface-config.service.d.ts +3 -1
- package/dist/surfaces/services/surface-config.service.js +33 -17
- package/dist/tool-call-visualization/components/ToolTabBodies.d.ts +0 -4
- package/dist/tool-call-visualization/components/ToolTabBodies.js +2 -25
- package/dist/tool-call-visualization/result-fields/ResultFile.js +2 -8
- package/dist/tool-call-visualization/result-fields/ShortId.js +1 -23
- package/dist/voice-agent/components/LiveVoiceDoor.js +1 -1
- package/dist/voice-agent/components/VoiceDebugPanel.js +1 -1
- package/dist/voice-agent/hooks/useVoiceAgentInstance.js +1 -1
- package/dist/window-panels/windows/agents/ObservationalMemoryWindow.d.ts +0 -17
- package/dist/window-panels/windows/agents/ObservationalMemoryWindow.js +7 -1
- package/package.json +7 -7
package/dist/host/ui-slots.d.ts
CHANGED
|
@@ -163,7 +163,7 @@ export interface ChatUiSlots {
|
|
|
163
163
|
SystemInstructionModal: AnyComponent;
|
|
164
164
|
confirm: AnyFn;
|
|
165
165
|
copyRichContent: AnyFn;
|
|
166
|
-
|
|
166
|
+
copyContent: AnyFn;
|
|
167
167
|
useTablesEverywhere: AnyFn;
|
|
168
168
|
useTextareaFormatting: AnyFn;
|
|
169
169
|
useClipboardPaste: AnyFn;
|
|
@@ -317,12 +317,10 @@ export interface ChatUiSlots {
|
|
|
317
317
|
dispatchWarRoomTool: AnyFn;
|
|
318
318
|
dispatchWarRoomMasterTool: AnyFn;
|
|
319
319
|
resolveGmailSendConnection: AnyFn;
|
|
320
|
-
voiceDisplayName: AnyFn;
|
|
321
320
|
canvasGetVersionHistory: (canvasId: string) => Promise<CanvasItemRow[]>;
|
|
322
321
|
canvasGetById: (canvasId: string) => Promise<CanvasItemRow | null>;
|
|
323
322
|
createSandboxFilesystemAdapter: AnyFn;
|
|
324
323
|
notesGetById: AnyFn;
|
|
325
|
-
isLiveConversationVoice: AnyFn;
|
|
326
324
|
createHtmlPage: AnyFn;
|
|
327
325
|
convertMarkdownToHtml: AnyFn;
|
|
328
326
|
sklActions: Record<string, AnyFn>;
|
|
@@ -338,7 +336,6 @@ export interface ChatUiSlots {
|
|
|
338
336
|
WorkspaceGate: AnyComponent;
|
|
339
337
|
OrganizationContextNotice: AnyComponent;
|
|
340
338
|
JsonInspector: AnyComponent;
|
|
341
|
-
InlineCopyButton: AnyComponent;
|
|
342
339
|
ConfirmDialog: SlotComponent<OpenChangeProps>;
|
|
343
340
|
ModelListDropdown: SlotComponent<ModelListDropdownProps>;
|
|
344
341
|
TextWithDoors: AnyComponent;
|
|
@@ -510,7 +507,7 @@ export declare const WebpageSnapshotView: AnyComponent;
|
|
|
510
507
|
export declare function hostFn<K extends keyof ChatUiSlots>(name: K, fallback?: AnyFn): ChatUiSlots[K];
|
|
511
508
|
export declare const confirm: AnyFn;
|
|
512
509
|
export declare const copyRichContent: AnyFn;
|
|
513
|
-
export declare const
|
|
510
|
+
export declare const copyContent: AnyFn;
|
|
514
511
|
export declare const useTablesEverywhere: AnyFn;
|
|
515
512
|
export declare const useTextareaFormatting: AnyFn;
|
|
516
513
|
export declare const useClipboardPaste: AnyFn;
|
|
@@ -604,7 +601,6 @@ export declare const StaleDataNotice: AnyComponent;
|
|
|
604
601
|
export declare const WorkspaceGate: AnyComponent;
|
|
605
602
|
export declare const OrganizationContextNotice: AnyComponent;
|
|
606
603
|
export declare const JsonInspector: AnyComponent;
|
|
607
|
-
export declare const InlineCopyButton: AnyComponent;
|
|
608
604
|
export declare const ConfirmDialog: SlotComponent<OpenChangeProps>;
|
|
609
605
|
export declare const ModelListDropdown: SlotComponent<ModelListDropdownProps>;
|
|
610
606
|
export declare const TextWithDoors: AnyComponent;
|
|
@@ -712,12 +708,10 @@ export declare const adoptCloudBrowserRunFromStream: AnyFn;
|
|
|
712
708
|
export declare const dispatchWarRoomTool: AnyFn;
|
|
713
709
|
export declare const dispatchWarRoomMasterTool: AnyFn;
|
|
714
710
|
export declare const resolveGmailSendConnection: AnyFn;
|
|
715
|
-
export declare const voiceDisplayName: AnyFn;
|
|
716
711
|
export declare const canvasGetVersionHistory: (canvasId: string) => Promise<CanvasItemRow[]>;
|
|
717
712
|
export declare const canvasGetById: (canvasId: string) => Promise<CanvasItemRow | null>;
|
|
718
713
|
export declare const createSandboxFilesystemAdapter: AnyFn;
|
|
719
714
|
export declare const notesGetById: AnyFn;
|
|
720
|
-
export declare const isLiveConversationVoice: AnyFn;
|
|
721
715
|
export declare const createHtmlPage: AnyFn;
|
|
722
716
|
export declare const convertMarkdownToHtml: AnyFn;
|
|
723
717
|
/** The host's skill-library action creators (`sklActions.x(...)`); resolved at call time, a bare host throws naming the slot. */
|
package/dist/host/ui-slots.js
CHANGED
|
@@ -4,6 +4,7 @@ import { formatCost, usdToPoints } from "@ai-matrx/kit/format";
|
|
|
4
4
|
import { reportUnregisteredHostSlot as reportUnregistered } from "./diagnostics.js";
|
|
5
5
|
import { DefaultWebpageSnapshotView } from "./defaults/webpage-snapshot-view.js";
|
|
6
6
|
import { DefaultFullScreenOverlay, DefaultWindowPanel } from "./defaults/window-panel.js";
|
|
7
|
+
import { copyText } from "@ai-matrx/kit/clipboard";
|
|
7
8
|
const slots = {};
|
|
8
9
|
function registerChatUi(next) {
|
|
9
10
|
Object.assign(slots, next);
|
|
@@ -68,13 +69,13 @@ const failingThunk = (name) => () => () => {
|
|
|
68
69
|
const STAND_INS = {
|
|
69
70
|
confirm: async () => false,
|
|
70
71
|
copyRichContent: async () => false,
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
72
|
+
// Content-shaped like the host's `copyContent(content, options)`: a string copies as text, anything
|
|
73
|
+
// else as JSON. A failed copy is reported through `onError` and returns false, never swallowed.
|
|
74
|
+
copyContent: async (content, options) => {
|
|
75
|
+
const text = typeof content === "string" ? content : JSON.stringify(content, null, 2);
|
|
76
|
+
const landed = await copyText(text ?? "");
|
|
77
|
+
if (!landed) options?.onError?.(new Error("Failed to copy"));
|
|
78
|
+
return landed;
|
|
78
79
|
},
|
|
79
80
|
useTablesEverywhere: () => NONE,
|
|
80
81
|
useCenterControlFit: () => true,
|
|
@@ -234,7 +235,7 @@ function hostFn(name, fallback) {
|
|
|
234
235
|
}
|
|
235
236
|
const confirm = slotFn("confirm");
|
|
236
237
|
const copyRichContent = slotFn("copyRichContent");
|
|
237
|
-
const
|
|
238
|
+
const copyContent = slotFn("copyContent");
|
|
238
239
|
const useTablesEverywhere = slotFn("useTablesEverywhere");
|
|
239
240
|
const useTextareaFormatting = slotFn("useTextareaFormatting", () => void 0);
|
|
240
241
|
const useClipboardPaste = slotFn("useClipboardPaste", () => void 0);
|
|
@@ -327,7 +328,6 @@ const StaleDataNotice = slotComponent("StaleDataNotice", unregisteredWidget("Sta
|
|
|
327
328
|
const WorkspaceGate = slotComponent("WorkspaceGate", unregisteredWidget("WorkspaceGate"));
|
|
328
329
|
const OrganizationContextNotice = slotComponent("OrganizationContextNotice", unregisteredWidget("OrganizationContextNotice"));
|
|
329
330
|
const JsonInspector = slotComponent("JsonInspector", unregisteredWidget("JsonInspector"));
|
|
330
|
-
const InlineCopyButton = slotComponent("InlineCopyButton", unregisteredWidget("InlineCopyButton"));
|
|
331
331
|
const ConfirmDialog = slotComponent("ConfirmDialog", unregisteredWidget("ConfirmDialog"));
|
|
332
332
|
const ModelListDropdown = slotComponent("ModelListDropdown", unregisteredWidget("ModelListDropdown"));
|
|
333
333
|
const TextWithDoors = slotComponent("TextWithDoors", unregisteredWidget("TextWithDoors"));
|
|
@@ -417,12 +417,10 @@ const adoptCloudBrowserRunFromStream = slotFn("adoptCloudBrowserRunFromStream");
|
|
|
417
417
|
const dispatchWarRoomTool = slotFn("dispatchWarRoomTool");
|
|
418
418
|
const dispatchWarRoomMasterTool = slotFn("dispatchWarRoomMasterTool");
|
|
419
419
|
const resolveGmailSendConnection = slotFn("resolveGmailSendConnection");
|
|
420
|
-
const voiceDisplayName = slotFn("voiceDisplayName", (_set, id) => id);
|
|
421
420
|
const canvasGetVersionHistory = slotFn("canvasGetVersionHistory");
|
|
422
421
|
const canvasGetById = slotFn("canvasGetById");
|
|
423
422
|
const createSandboxFilesystemAdapter = slotFn("createSandboxFilesystemAdapter");
|
|
424
423
|
const notesGetById = slotFn("notesGetById");
|
|
425
|
-
const isLiveConversationVoice = slotFn("isLiveConversationVoice", () => false);
|
|
426
424
|
const createHtmlPage = slotFn("createHtmlPage");
|
|
427
425
|
const convertMarkdownToHtml = slotFn("convertMarkdownToHtml");
|
|
428
426
|
const sklActions = new Proxy({}, { get: (_t, prop) => (...args) => {
|
|
@@ -556,7 +554,6 @@ export {
|
|
|
556
554
|
IconButton,
|
|
557
555
|
InPlaceEditor,
|
|
558
556
|
InfoHint,
|
|
559
|
-
InlineCopyButton,
|
|
560
557
|
InputCapabilitiesEditor,
|
|
561
558
|
ItemMenu,
|
|
562
559
|
ItemRow,
|
|
@@ -636,8 +633,8 @@ export {
|
|
|
636
633
|
confirm,
|
|
637
634
|
connectorDefinitionFromMcp,
|
|
638
635
|
convertMarkdownToHtml,
|
|
636
|
+
copyContent,
|
|
639
637
|
copyRichContent,
|
|
640
|
-
copyToClipboard,
|
|
641
638
|
createHtmlPage,
|
|
642
639
|
createSandboxFilesystemAdapter,
|
|
643
640
|
currentCostUnit,
|
|
@@ -668,7 +665,6 @@ export {
|
|
|
668
665
|
humanLines,
|
|
669
666
|
invalidateCanvasItemCache,
|
|
670
667
|
invalidateMandateCatalogueCache,
|
|
671
|
-
isLiveConversationVoice,
|
|
672
668
|
isSkillStreamEvent,
|
|
673
669
|
isUuidValue,
|
|
674
670
|
isWarRoomThreadAgentSurface,
|
|
@@ -771,6 +767,5 @@ export {
|
|
|
771
767
|
useSkills,
|
|
772
768
|
useTablesEverywhere,
|
|
773
769
|
useTextareaFormatting,
|
|
774
|
-
useUrlSync
|
|
775
|
-
voiceDisplayName
|
|
770
|
+
useUrlSync
|
|
776
771
|
};
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
Share2
|
|
18
18
|
} from "lucide-react";
|
|
19
19
|
import { getMarkdownStylesheet } from "@ai-matrx/print/markdown";
|
|
20
|
-
import { AdvancedMenu,
|
|
20
|
+
import { AdvancedMenu, copyContent } from "../../host/ui-slots.js";
|
|
21
21
|
import { EmailInputDialog } from "../../host/ui-slots.js";
|
|
22
22
|
import { AuthGateDialog } from "../../host/ui-slots.js";
|
|
23
23
|
import { notesCreate } from "../../host/ui-slots.js";
|
|
@@ -29,6 +29,7 @@ import { openOverlay, CHAT_WINDOWS } from "../../host/windows.js";
|
|
|
29
29
|
import { kindTextToMarkdown } from "../../utils/content-ir/surfaces/kind-text-to-markdown.js";
|
|
30
30
|
import { removeCodeSpans, replaceFences } from "@ai-matrx/content-ir/source";
|
|
31
31
|
import { selectOrganizationId, ensureOrganizationContext, isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
32
|
+
import { downloadFile } from "@ai-matrx/kit/download";
|
|
32
33
|
const PENDING_ACTION_KEY = "matrx_pending_post_auth_action";
|
|
33
34
|
const PublicMessageOptionsMenu = ({
|
|
34
35
|
content: answerContent,
|
|
@@ -124,7 +125,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
124
125
|
onClose();
|
|
125
126
|
};
|
|
126
127
|
const handleCopyPlain = async () => {
|
|
127
|
-
await
|
|
128
|
+
await copyContent(content, {
|
|
128
129
|
onSuccess: () => {
|
|
129
130
|
},
|
|
130
131
|
onError: (error) => {
|
|
@@ -133,7 +134,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
133
134
|
});
|
|
134
135
|
};
|
|
135
136
|
const handleCopyGoogleDocs = async () => {
|
|
136
|
-
await
|
|
137
|
+
await copyContent(content, {
|
|
137
138
|
isMarkdown: true,
|
|
138
139
|
formatForGoogleDocs: true,
|
|
139
140
|
onSuccess: () => {
|
|
@@ -146,7 +147,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
146
147
|
});
|
|
147
148
|
};
|
|
148
149
|
const handleCopyWithThinking = async () => {
|
|
149
|
-
await
|
|
150
|
+
await copyContent(content, {
|
|
150
151
|
isMarkdown: true,
|
|
151
152
|
includeThinking: true,
|
|
152
153
|
onSuccess: () => {
|
|
@@ -166,7 +167,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
166
167
|
toast.info("HTML preview not available here");
|
|
167
168
|
return;
|
|
168
169
|
}
|
|
169
|
-
await
|
|
170
|
+
await copyContent(content, {
|
|
170
171
|
isMarkdown: true,
|
|
171
172
|
formatForWordPress: true,
|
|
172
173
|
showHtmlPreview: true,
|
|
@@ -209,7 +210,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
209
210
|
}
|
|
210
211
|
};
|
|
211
212
|
const handleCopyCompleteHTML = async () => {
|
|
212
|
-
await
|
|
213
|
+
await copyContent(content, {
|
|
213
214
|
isMarkdown: true,
|
|
214
215
|
formatForWordPress: true,
|
|
215
216
|
showHtmlPreview: true,
|
|
@@ -228,7 +229,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
228
229
|
${filteredHtml}
|
|
229
230
|
</body>
|
|
230
231
|
</html>`;
|
|
231
|
-
await
|
|
232
|
+
await copyContent(completeHTML, {
|
|
232
233
|
onSuccess: () => {
|
|
233
234
|
},
|
|
234
235
|
onError: (error) => {
|
|
@@ -248,15 +249,7 @@ const PublicMessageOptionsMenu = ({
|
|
|
248
249
|
};
|
|
249
250
|
const handleSaveAsFile = () => {
|
|
250
251
|
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
251
|
-
|
|
252
|
-
const url = URL.createObjectURL(blob);
|
|
253
|
-
const link = document.createElement("a");
|
|
254
|
-
link.href = url;
|
|
255
|
-
link.download = `ai-response-${timestamp}.md`;
|
|
256
|
-
document.body.appendChild(link);
|
|
257
|
-
link.click();
|
|
258
|
-
document.body.removeChild(link);
|
|
259
|
-
URL.revokeObjectURL(url);
|
|
252
|
+
downloadFile(`ai-response-${timestamp}.md`, content, "text/markdown;charset=utf-8");
|
|
260
253
|
onClose();
|
|
261
254
|
};
|
|
262
255
|
const handleEmailToMe = async () => {
|
|
@@ -1,5 +1,14 @@
|
|
|
1
|
+
import { type FilesHost } from "@ai-matrx/media/files/engine";
|
|
1
2
|
import type { ChatState } from "./state.js";
|
|
2
|
-
export
|
|
3
|
+
export interface CreateChatStoreOptions {
|
|
4
|
+
/**
|
|
5
|
+
* The files engine's host (database, server client, optional scope/org/share/notify) for a
|
|
6
|
+
* host that has not called `configureFilesHost` itself. The engine is then wired to THIS
|
|
7
|
+
* store, so file thunks read and write the slice chat renders from.
|
|
8
|
+
*/
|
|
9
|
+
files?: Omit<FilesHost, "store">;
|
|
10
|
+
}
|
|
11
|
+
export declare function createChatStore(preloadedState?: Partial<ChatState>, options?: CreateChatStoreOptions): import("@reduxjs/toolkit").EnhancedStore<{
|
|
3
12
|
voiceAgent: import("../voice-agent/types.js").VoiceAgentState;
|
|
4
13
|
agentDefinition: import("../agents/types/agent-definition.types.js").AgentDefinitionSliceState;
|
|
5
14
|
conversationList: import("../agents/redux/conversation-list/conversation-list.types.js").ConversationListState;
|
|
@@ -4,12 +4,13 @@ import { fork } from "redux-saga/effects";
|
|
|
4
4
|
import {
|
|
5
5
|
cloudFilesMutationToastMiddleware,
|
|
6
6
|
cloudFilesRealtimeMiddleware,
|
|
7
|
-
cloudFilesReducer
|
|
7
|
+
cloudFilesReducer,
|
|
8
|
+
configureFilesHost
|
|
8
9
|
} from "@ai-matrx/media/files/engine";
|
|
9
10
|
import { chatReducers } from "./slices.js";
|
|
10
11
|
import { chatMiddlewares } from "./middlewares.js";
|
|
11
12
|
import { chatSagas } from "./sagas.js";
|
|
12
|
-
function createChatStore(preloadedState) {
|
|
13
|
+
function createChatStore(preloadedState, options = {}) {
|
|
13
14
|
const sagaMiddleware = createSagaMiddleware();
|
|
14
15
|
const store = configureStore({
|
|
15
16
|
// Files are part of chat (P16f): the files engine's slice and its two middlewares come
|
|
@@ -30,6 +31,7 @@ function createChatStore(preloadedState) {
|
|
|
30
31
|
),
|
|
31
32
|
devTools: process.env.NODE_ENV !== "production"
|
|
32
33
|
});
|
|
34
|
+
if (options.files) configureFilesHost({ ...options.files, store: () => store });
|
|
33
35
|
sagaMiddleware.run(function* chatRootSaga() {
|
|
34
36
|
for (const saga of chatSagas()) yield fork(saga);
|
|
35
37
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type LiveValuesStore } from "@ai-matrx/alchemy/surface";
|
|
1
2
|
import { type ReactNode } from "react";
|
|
2
3
|
import type { SurfaceScopePayload } from "../types.js";
|
|
3
4
|
import type { InstanceContextEntry } from "../../agents/types/instance.types.js";
|
|
@@ -198,6 +199,15 @@ export interface SurfaceRegistry {
|
|
|
198
199
|
/** Called after every registration change. */
|
|
199
200
|
subscribe: (listener: () => void) => () => void;
|
|
200
201
|
}
|
|
202
|
+
/**
|
|
203
|
+
* THE PAGE'S LIVE VALUES REACH THE AGENT (ALC-18). A value the surface DECLARES that its runtime
|
|
204
|
+
* and contributions left unset is answered from the page's live capture (`@ai-matrx/alchemy/surface`
|
|
205
|
+
* `liveValues`: identity, selection, sections), only while the publishing page IS this surface —
|
|
206
|
+
* the same rule as `createSurfacePort({ live })`'s `getValue`. A supplied value always wins, and an
|
|
207
|
+
* undeclared live name (the request log, a section nobody declared) never rides along. Every reader
|
|
208
|
+
* of `getScope()` — the send path's context entries, the context window, write-back — gets it.
|
|
209
|
+
*/
|
|
210
|
+
export declare function withLiveValues(surfaceName: string, loaded: SurfaceScopePayload, live?: LiveValuesStore): SurfaceScopePayload;
|
|
201
211
|
/**
|
|
202
212
|
* The hosts `surfaceName` was mounted inside earlier in this page session
|
|
203
213
|
* that are STILL mounted, deepest first. Empty when `surfaceName` itself is
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
3
|
import { announceUndeclaredLoadedValues } from "./loaded-value-check.js";
|
|
4
|
+
import { liveValueOf, liveValues } from "@ai-matrx/alchemy/surface";
|
|
5
|
+
import { getManifest } from "./registry.js";
|
|
4
6
|
import {
|
|
5
7
|
createContext,
|
|
6
8
|
useCallback,
|
|
@@ -15,6 +17,25 @@ import {
|
|
|
15
17
|
useAlchemySurfaceHandle
|
|
16
18
|
} from "../../agent-copy/AlchemySurfaceBridge.js";
|
|
17
19
|
let nextId = 0;
|
|
20
|
+
function withLiveValues(surfaceName, loaded, live = liveValues) {
|
|
21
|
+
const declared = getManifest(surfaceName)?.values ?? [];
|
|
22
|
+
const missing = declared.filter((v) => !(v.name in loaded));
|
|
23
|
+
if (missing.length === 0) return loaded;
|
|
24
|
+
let capture;
|
|
25
|
+
try {
|
|
26
|
+
capture = live.readFor(surfaceName);
|
|
27
|
+
} catch (err) {
|
|
28
|
+
console.error(`[surfaces] the live values of "${surfaceName}" could not be read`, err);
|
|
29
|
+
return loaded;
|
|
30
|
+
}
|
|
31
|
+
if (!capture) return loaded;
|
|
32
|
+
const filled = { ...loaded };
|
|
33
|
+
for (const v of missing) {
|
|
34
|
+
const value = liveValueOf(capture, v.name);
|
|
35
|
+
if (value !== void 0) filled[v.name] = value;
|
|
36
|
+
}
|
|
37
|
+
return filled;
|
|
38
|
+
}
|
|
18
39
|
function createRegistry(kind, onRegister) {
|
|
19
40
|
let stack = [];
|
|
20
41
|
const listeners = /* @__PURE__ */ new Set();
|
|
@@ -70,7 +91,7 @@ function createRegistry(kind, onRegister) {
|
|
|
70
91
|
}
|
|
71
92
|
const loaded = { ...own, ...contributed };
|
|
72
93
|
announceUndeclaredLoadedValues(surfaceName, loaded);
|
|
73
|
-
return loaded;
|
|
94
|
+
return withLiveValues(surfaceName, loaded);
|
|
74
95
|
};
|
|
75
96
|
return () => {
|
|
76
97
|
const own = getScope();
|
|
@@ -531,5 +552,6 @@ export {
|
|
|
531
552
|
waitForCapturedRuntime,
|
|
532
553
|
wasPageOwnConversationOf,
|
|
533
554
|
wasSurfaceMountedThisSession,
|
|
555
|
+
withLiveValues,
|
|
534
556
|
withScopeContributions
|
|
535
557
|
};
|
|
@@ -115,7 +115,9 @@ export declare function setRoleSelection(args: {
|
|
|
115
115
|
scope: PrefScopeInput;
|
|
116
116
|
}): Promise<void>;
|
|
117
117
|
/** Move one agent choice / roster item to Trash (restorable; re-selecting revives it). */
|
|
118
|
-
export declare function deleteRolePref(prefId: string
|
|
118
|
+
export declare function deleteRolePref(prefId: string, opts?: {
|
|
119
|
+
platformTier?: boolean;
|
|
120
|
+
}): Promise<void>;
|
|
119
121
|
export declare function addRosterItem(args: {
|
|
120
122
|
surfaceName: string;
|
|
121
123
|
roleName: string;
|
|
@@ -279,6 +279,9 @@ function matchScope(q, scope, tierOrganization) {
|
|
|
279
279
|
}
|
|
280
280
|
return q.is("user_id", null).is("scope_id", null).eq("organization_id", tierOrganization);
|
|
281
281
|
}
|
|
282
|
+
function withPlatformRoleAdminLane(request, on) {
|
|
283
|
+
return on ? request.setHeader("x-matrx-admin-lane", "1") : request;
|
|
284
|
+
}
|
|
282
285
|
async function setRoleSelection(args) {
|
|
283
286
|
const {
|
|
284
287
|
surfaceName,
|
|
@@ -291,33 +294,46 @@ async function setRoleSelection(args) {
|
|
|
291
294
|
const client = sb();
|
|
292
295
|
let q = client.schema("ui").from("ui_surface_agent_pref").select("id").eq("surface_name", surfaceName).eq("role_name", roleName).eq("kind", "selection").eq("position", position);
|
|
293
296
|
q = matchScope(q, scope, await tierOrganizationFor(scope));
|
|
294
|
-
const
|
|
297
|
+
const platformLane = scope.global === true;
|
|
298
|
+
const { data: existing, error: findErr } = await withPlatformRoleAdminLane(
|
|
299
|
+
q,
|
|
300
|
+
platformLane
|
|
301
|
+
).maybeSingle();
|
|
295
302
|
if (findErr) throw findErr;
|
|
296
303
|
if (existing) {
|
|
297
304
|
await writeOne(
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
withPlatformRoleAdminLane(
|
|
306
|
+
client.schema("ui").from("ui_surface_agent_pref").update({
|
|
307
|
+
agent_id: agentId,
|
|
308
|
+
deleted_at: null,
|
|
309
|
+
...settings ? { settings } : {}
|
|
310
|
+
}).eq("id", existing.id).select("id"),
|
|
311
|
+
platformLane
|
|
312
|
+
),
|
|
303
313
|
{ action: "save", noun: "agent choice" }
|
|
304
314
|
);
|
|
305
315
|
return;
|
|
306
316
|
}
|
|
307
|
-
const { error } = await
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
317
|
+
const { error } = await withPlatformRoleAdminLane(
|
|
318
|
+
client.schema("ui").from("ui_surface_agent_pref").insert({
|
|
319
|
+
surface_name: surfaceName,
|
|
320
|
+
role_name: roleName,
|
|
321
|
+
agent_id: agentId,
|
|
322
|
+
kind: "selection",
|
|
323
|
+
position,
|
|
324
|
+
settings: settings ?? {},
|
|
325
|
+
...await scopeInsertColumns(scope)
|
|
326
|
+
}),
|
|
327
|
+
platformLane
|
|
328
|
+
);
|
|
316
329
|
if (error) throw error;
|
|
317
330
|
}
|
|
318
|
-
async function deleteRolePref(prefId) {
|
|
331
|
+
async function deleteRolePref(prefId, opts = {}) {
|
|
319
332
|
await writeOne(
|
|
320
|
-
|
|
333
|
+
withPlatformRoleAdminLane(
|
|
334
|
+
sb().schema("ui").from("ui_surface_agent_pref").update({ deleted_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", prefId).is("deleted_at", null).select("id"),
|
|
335
|
+
opts.platformTier === true
|
|
336
|
+
),
|
|
321
337
|
{ action: "remove", noun: "agent choice" }
|
|
322
338
|
);
|
|
323
339
|
}
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { ToolLifecycleEntry } from "../../agents/types/request.types.js";
|
|
3
3
|
import type { ToolOverlayTabSpec, ToolRendererProps } from "../types.js";
|
|
4
|
-
export declare const CopyButton: React.FC<{
|
|
5
|
-
text: string;
|
|
6
|
-
className?: string;
|
|
7
|
-
}>;
|
|
8
4
|
export declare const InputView: React.FC<{
|
|
9
5
|
entry: ToolLifecycleEntry;
|
|
10
6
|
}>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { resultToHuman } from "../utils/human-copy.js";
|
|
4
|
-
import React
|
|
4
|
+
import React from "react";
|
|
5
5
|
import { useToolConversationId } from "./ToolConversationContext.js";
|
|
6
|
-
import {
|
|
6
|
+
import { CircleAlert, FileCode2, Route, Settings2 } from "lucide-react";
|
|
7
7
|
import { Badge } from "@ai-matrx/design-system";
|
|
8
8
|
import { CopyButtons } from "../../host/ui-slots.js";
|
|
9
9
|
import { JsonInspector } from "../../host/ui-slots.js";
|
|
@@ -19,7 +19,6 @@ import {
|
|
|
19
19
|
toolEntryBundleToHuman
|
|
20
20
|
} from "../utils/toolEntryBundle.js";
|
|
21
21
|
import { ErrorAlchemyMenu } from "../../host/ui-slots.js";
|
|
22
|
-
import { Button } from "@ai-matrx/design-system/controls";
|
|
23
22
|
function buildAgentInput(entry, description, data) {
|
|
24
23
|
return {
|
|
25
24
|
kind: "tool-result",
|
|
@@ -29,27 +28,6 @@ function buildAgentInput(entry, description, data) {
|
|
|
29
28
|
attributes: { tool: entry.toolName, status: entry.status }
|
|
30
29
|
};
|
|
31
30
|
}
|
|
32
|
-
const CopyButton = ({
|
|
33
|
-
text,
|
|
34
|
-
className
|
|
35
|
-
}) => {
|
|
36
|
-
const [copied, setCopied] = useState(false);
|
|
37
|
-
const handleCopy = async () => {
|
|
38
|
-
try {
|
|
39
|
-
await navigator.clipboard.writeText(text);
|
|
40
|
-
} catch {
|
|
41
|
-
const textarea = document.createElement("textarea");
|
|
42
|
-
textarea.value = text;
|
|
43
|
-
document.body.appendChild(textarea);
|
|
44
|
-
textarea.select();
|
|
45
|
-
document.execCommand("copy");
|
|
46
|
-
document.body.removeChild(textarea);
|
|
47
|
-
}
|
|
48
|
-
setCopied(true);
|
|
49
|
-
setTimeout(() => setCopied(false), 2e3);
|
|
50
|
-
};
|
|
51
|
-
return /* @__PURE__ */ jsx(Button, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx(Check, {}) : /* @__PURE__ */ jsx(Copy, {}), glyphTone: copied ? "success" : void 0, onClick: handleCopy, title: copied ? "Copied!" : "Copy to clipboard", className, children: copied ? "Copied" : "Copy" });
|
|
52
|
-
};
|
|
53
31
|
const InputView = ({
|
|
54
32
|
entry
|
|
55
33
|
}) => {
|
|
@@ -225,7 +203,6 @@ const CustomOverlayBody = ({ entry, Component, conversationId: conversationIdPro
|
|
|
225
203
|
) }) });
|
|
226
204
|
};
|
|
227
205
|
export {
|
|
228
|
-
CopyButton,
|
|
229
206
|
CustomOverlayBody,
|
|
230
207
|
EntryResultsBody,
|
|
231
208
|
ErrorView,
|
|
@@ -8,6 +8,7 @@ import { formatFileSize } from "@ai-matrx/kit/format";
|
|
|
8
8
|
import { useFileActions } from "../../host/ui-slots.js";
|
|
9
9
|
import { useMediaResolution } from "@ai-matrx/media/core";
|
|
10
10
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
11
|
+
import { downloadUrl } from "@ai-matrx/kit/download";
|
|
11
12
|
function deriveName(file) {
|
|
12
13
|
if (file.file_name && file.file_name.trim().length > 0) return file.file_name.trim();
|
|
13
14
|
const src = file.download_url ?? file.url;
|
|
@@ -33,14 +34,7 @@ function deriveTypeLabel(file, name) {
|
|
|
33
34
|
return null;
|
|
34
35
|
}
|
|
35
36
|
function triggerAnchorDownload(href, name) {
|
|
36
|
-
|
|
37
|
-
a.href = href;
|
|
38
|
-
a.download = name;
|
|
39
|
-
a.target = "_blank";
|
|
40
|
-
a.rel = "noopener noreferrer";
|
|
41
|
-
document.body.appendChild(a);
|
|
42
|
-
a.click();
|
|
43
|
-
a.remove();
|
|
37
|
+
downloadUrl(href, name, { newTab: true });
|
|
44
38
|
}
|
|
45
39
|
const ResultFile = ({ file, density = "inline", className }) => {
|
|
46
40
|
const [busy, setBusy] = useState(false);
|
|
@@ -2,31 +2,9 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import React from "react";
|
|
4
4
|
import { Check, Copy } from "lucide-react";
|
|
5
|
+
import { copyText } from "@ai-matrx/kit/clipboard";
|
|
5
6
|
import { cn } from "@ai-matrx/design-system";
|
|
6
7
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
7
|
-
async function copyText(text) {
|
|
8
|
-
try {
|
|
9
|
-
if (navigator.clipboard?.writeText) {
|
|
10
|
-
await navigator.clipboard.writeText(text);
|
|
11
|
-
return true;
|
|
12
|
-
}
|
|
13
|
-
} catch {
|
|
14
|
-
}
|
|
15
|
-
try {
|
|
16
|
-
const ta = document.createElement("textarea");
|
|
17
|
-
ta.value = text;
|
|
18
|
-
ta.style.position = "fixed";
|
|
19
|
-
ta.style.opacity = "0";
|
|
20
|
-
ta.style.pointerEvents = "none";
|
|
21
|
-
document.body.appendChild(ta);
|
|
22
|
-
ta.select();
|
|
23
|
-
const ok = document.execCommand("copy");
|
|
24
|
-
document.body.removeChild(ta);
|
|
25
|
-
return ok;
|
|
26
|
-
} catch {
|
|
27
|
-
return false;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
8
|
const ShortId = ({
|
|
31
9
|
value,
|
|
32
10
|
variant = "compact",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { SettingDoor } from "../../host/prefs-react.js";
|
|
4
4
|
import { useAppSelector } from "../../store/hooks.js";
|
|
5
|
-
import { voiceDisplayName } from "
|
|
5
|
+
import { voiceDisplayName } from "@ai-matrx/media/voices";
|
|
6
6
|
function LiveVoiceDoor({
|
|
7
7
|
voiceId,
|
|
8
8
|
agentId
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
useRealtimeSessionConfig
|
|
13
13
|
} from "../realtimeSession.js";
|
|
14
14
|
import { useSessionKnob } from "../../host/prefs-react.js";
|
|
15
|
-
import { isLiveConversationVoice } from "
|
|
15
|
+
import { isLiveConversationVoice } from "@ai-matrx/media/voices";
|
|
16
16
|
const LIVE_CONVERSATION_VOICE_KNOB = "media.conversation.voice";
|
|
17
17
|
function isVoiceId(v) {
|
|
18
18
|
return isLiveConversationVoice(v);
|
|
@@ -1,20 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ObservationalMemoryWindow
|
|
3
|
-
*
|
|
4
|
-
* Admin-only floating inspector for the Observational Memory feature.
|
|
5
|
-
* Wraps `ObservationalMemoryCore` in the standard WindowPanel shell with a
|
|
6
|
-
* sidebar listing every conversation the session has seen memory activity
|
|
7
|
-
* for — that means either:
|
|
8
|
-
* - the conversation has a persisted `observational_memory` metadata block
|
|
9
|
-
* (hydrated on conversation load), OR
|
|
10
|
-
* - we have received at least one `memory_*` stream event for it this
|
|
11
|
-
* session, OR
|
|
12
|
-
* - an authoritative cost summary has been fetched for it.
|
|
13
|
-
*
|
|
14
|
-
* See `/window-panel-authoring` for the registration contract. This window is
|
|
15
|
-
* persisted (NOT ephemeral) — admins get their last-selected conversation
|
|
16
|
-
* back after a reload, matching the per-conversation nature of the feature.
|
|
17
|
-
*/
|
|
18
1
|
import React from "react";
|
|
19
2
|
interface ObservationalMemoryWindowProps {
|
|
20
3
|
isOpen: boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useClipboard } from "@ai-matrx/kit/clipboard";
|
|
4
|
+
import { toast } from "../../../host/notify.js";
|
|
3
5
|
import { useCallback, useMemo, useState } from "react";
|
|
4
6
|
import {
|
|
5
7
|
Brain,
|
|
@@ -36,9 +38,13 @@ import {
|
|
|
36
38
|
import { CHAT_WINDOWS } from "../../../host/windows.js";
|
|
37
39
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
38
40
|
function useCopyText(text) {
|
|
41
|
+
const { copyText } = useClipboard({
|
|
42
|
+
notify: (message, kind) => kind === "error" ? toast.error(message) : toast.success(message)
|
|
43
|
+
});
|
|
39
44
|
const [copied, setCopied] = useState(false);
|
|
40
45
|
const copy = useCallback(() => {
|
|
41
|
-
|
|
46
|
+
copyText(text).then((copied2) => {
|
|
47
|
+
if (!copied2) return;
|
|
42
48
|
setCopied(true);
|
|
43
49
|
setTimeout(() => setCopied(false), 1500);
|
|
44
50
|
});
|