@ai-matrx/chat 0.4.10 → 0.4.14
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 +74 -0
- package/dist/agents/components/context-items/bodies/ContextInputBody.js +1 -1
- package/dist/agents/components/context-items/bodies/GenericBody.js +1 -1
- package/dist/agents/components/conversation-actions/conversation-verbs.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
- package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
- package/dist/agents/components/live-run/LiveRunProgress.js +1 -1
- package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
- package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +2 -2
- package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
- package/dist/agents/components/messages-display/conversation-tools/find-in-conversation.js +1 -1
- package/dist/agents/components/messages-display/message-options/buildTaskSeedFromMessage.js +1 -1
- package/dist/agents/components/messages-display/user/AgentUserMessage.js +1 -1
- package/dist/agents/components/messages-display/user/FirstTurnVariables.js +1 -1
- package/dist/agents/components/run/AgentStatusIndicator.js +1 -1
- package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
- package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
- package/dist/agents/components/shared/AgentPlanningIndicator.js +1 -1
- package/dist/agents/conversation-export/conversation-transfer.js +1 -1
- package/dist/agents/conversation-export/document-markdown.js +1 -1
- package/dist/agents/hooks/useConversationRoutePromotion.js +1 -1
- package/dist/agents/hooks/useModelControls.js +1 -1
- package/dist/agents/redux/agent-definition/converters.js +1 -1
- package/dist/agents/redux/agent-definition/slice.js +1 -1
- package/dist/agents/redux/conversation-list/conversation-list.thunks.js +1 -1
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +2 -2
- package/dist/agents/redux/execution-system/active-requests/active-requests.slice.d.ts +2 -0
- package/dist/agents/redux/execution-system/active-requests/active-requests.slice.js +7 -0
- package/dist/agents/redux/execution-system/conversations/conversation-persistence.js +2 -4
- package/dist/agents/redux/execution-system/instance-context/sync-canvas-item-context.thunk.js +1 -1
- package/dist/agents/redux/execution-system/thunks/dispatch-matrx-extend-tool.thunk.js +3 -1
- package/dist/agents/redux/execution-system/thunks/process-stream.js +27 -24
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.d.ts +7 -0
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.js +13 -0
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +1 -1
- package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/output-contract-guard.js +1 -1
- package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +8 -8
- package/dist/agents/runtime-reconnect/api.d.ts +6 -25
- package/dist/agents/runtime-reconnect/api.js +7 -13
- package/dist/agents/runtime-reconnect/reconnect-server-operation.thunk.js +167 -159
- package/dist/agents/runtime-reconnect/types.d.ts +2 -0
- package/dist/agents/services/mcp-connections.service.d.ts +12 -0
- package/dist/agents/services/mcp-connections.service.js +4 -7
- package/dist/agents/types/request.types.d.ts +6 -0
- package/dist/agents/utils/canvasItemContext.js +1 -1
- package/dist/agents/utils/json-extraction.js +2 -2
- package/dist/canvas/workspace/ChatPanelTitleMenu.js +1 -1
- package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +1 -1
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/core/ChatConversationClient.js +1 -1
- package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +1 -1
- package/dist/cx-conversation/AssistantMessage.js +1 -1
- package/dist/host/configure.js +15 -5
- package/dist/host/contract.d.ts +43 -2
- package/dist/host/db.js +6 -0
- package/dist/host/defaults/diagnostics.d.ts +5 -0
- package/dist/host/defaults/diagnostics.js +1 -2
- package/dist/host/defaults/identity.d.ts +26 -0
- package/dist/host/defaults/identity.js +133 -1
- package/dist/host/identity.d.ts +19 -2
- package/dist/host/identity.js +18 -10
- package/dist/host/session-retry.js +2 -2
- package/dist/mandates/llm-params.d.ts +1 -1
- package/dist/mandates/output-contract.js +1 -1
- package/dist/mandates/service.d.ts +1 -1
- package/dist/mandates/service.js +1 -1
- package/dist/mandates/test-run-core.js +1 -1
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
- package/dist/surfaces/services/bind-agent-to-surface.service.js +2 -4
- package/dist/surfaces/services/surface-config.service.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallBatch.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallVisualization.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +2 -2
- package/dist/tool-call-visualization/renderers/agent-call/collab-subtitle.js +3 -3
- package/dist/tool-call-visualization/renderers/skill/SkillInline.js +1 -1
- package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
- package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
- package/dist/tool-call-visualization/result-fields/shape.js +1 -1
- package/dist/tool-call-visualization/utils/cxToolCallToLifecycleEntry.js +2 -2
- package/dist/tool-call-visualization/utils/human-copy.js +3 -3
- package/dist/ui/mandates-storage/provision-shapes.d.ts +1 -1
- package/dist/ui/mandates-storage/provision-shapes.js +1 -1
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1 -1
- package/dist/ui/treatment-shape.d.ts +1 -1
- package/dist/ui/treatment-shape.js +1 -1
- package/dist/voice-agent/relay/useVoiceRelaySession.js +1 -1
- package/package.json +24 -6
- package/dist/agents/hooks/useWarmAgent.d.ts +0 -8
- package/dist/agents/hooks/useWarmAgent.js +0 -25
- package/dist/agents/utils/artifactId.d.ts +0 -34
- package/dist/agents/utils/artifactId.js +0 -15
- package/dist/ui/ShimmerText.d.ts +0 -5
- package/dist/ui/ShimmerText.js +0 -21
- package/dist/ui/addressWithoutNavigating.d.ts +0 -68
- package/dist/ui/addressWithoutNavigating.js +0 -60
- package/dist/utils/content-ir/decision-answers-ids.d.ts +0 -3
- package/dist/utils/content-ir/decision-answers-ids.js +0 -6
- package/dist/utils/content-ir/envelope-parity.d.ts +0 -12
- package/dist/utils/content-ir/envelope-parity.js +0 -32
- package/dist/utils/content-ir/instance-title.d.ts +0 -26
- package/dist/utils/content-ir/instance-title.js +0 -39
- package/dist/utils/content-ir/kinds/kind-markdown-utils.d.ts +0 -84
- package/dist/utils/content-ir/kinds/kind-markdown-utils.js +0 -233
- package/dist/utils/content-ir/kinds/kind-value-markdown.d.ts +0 -5
- package/dist/utils/content-ir/kinds/kind-value-markdown.js +0 -17
- package/dist/utils/content-ir/legacy-quiz-envelope.d.ts +0 -3
- package/dist/utils/content-ir/legacy-quiz-envelope.js +0 -45
- package/dist/utils/content-ir/surfaces/embedded-kind-json.d.ts +0 -140
- package/dist/utils/content-ir/surfaces/embedded-kind-json.js +0 -527
- package/dist/utils/content-ir/surfaces/json-kind-signal.d.ts +0 -307
- package/dist/utils/content-ir/surfaces/json-kind-signal.js +0 -945
- package/dist/utils/content-ir/surfaces/kind-image-alt.d.ts +0 -27
- package/dist/utils/content-ir/surfaces/kind-image-alt.js +0 -117
- package/dist/utils/content-ir/surfaces/kind-one-line.d.ts +0 -67
- package/dist/utils/content-ir/surfaces/kind-one-line.js +0 -209
- package/dist/utils/content-ir/surfaces/kind-text-label.d.ts +0 -20
- package/dist/utils/content-ir/surfaces/kind-text-label.js +0 -50
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.d.ts +0 -47
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.js +0 -399
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.d.ts +0 -54
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.js +0 -128
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.d.ts +0 -61
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.js +0 -215
- package/dist/utils/inline-decision/decision-options.d.ts +0 -21
- package/dist/utils/inline-decision/decision-options.js +0 -32
- package/dist/utils/json.d.ts +0 -63
- package/dist/utils/json.js +0 -22
- package/dist/utils/markdown/plain-title.d.ts +0 -25
- package/dist/utils/markdown/plain-title.js +0 -51
- package/dist/utils/rendered-find.d.ts +0 -9
- package/dist/utils/rendered-find.js +0 -68
- package/dist/utils/rich-editor/core/caret-context.d.ts +0 -24
- package/dist/utils/rich-editor/core/caret-context.js +0 -73
- package/dist/utils/rich-editor/in-place/caret-handoff.d.ts +0 -3
- package/dist/utils/rich-editor/in-place/caret-handoff.js +0 -15
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
extractFirstJson
|
|
3
|
-
} from "@ai-matrx/
|
|
4
|
-
import { findAllFencedBlocks } from "@ai-matrx/
|
|
3
|
+
} from "@ai-matrx/content-ir/json-extract";
|
|
4
|
+
import { findAllFencedBlocks } from "@ai-matrx/content-ir/json-extract";
|
|
5
5
|
function extractJsonFromText(text) {
|
|
6
6
|
if (!text || typeof text !== "string") {
|
|
7
7
|
return { success: false, error: "No text provided", rawText: text || "" };
|
|
@@ -8,7 +8,7 @@ import { useAppSelector } from "../../store/hooks.js";
|
|
|
8
8
|
import { selectConversationTitle } from "../../agents/redux/execution-system/conversations/conversations.selectors.js";
|
|
9
9
|
import { selectConversationListItemById } from "../../agents/redux/conversation-list/conversation-list.selectors.js";
|
|
10
10
|
import { conversationRenameOpener } from "../../agents/components/conversation-actions/rename/conversationRenameOpener.js";
|
|
11
|
-
import { conversationTitleText } from "
|
|
11
|
+
import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
|
|
12
12
|
import { Button, Tile } from "@ai-matrx/design-system/controls";
|
|
13
13
|
import { ConversationHistorySidebar } from "../../agents/components/conversation-history/ConversationHistorySidebar.js";
|
|
14
14
|
const PANEL_HISTORY_SCOPE = "chat-panel-menu";
|
|
@@ -7,7 +7,7 @@ import { resumeConversation } from "../../agents/redux/execution-system/thunks/r
|
|
|
7
7
|
import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
|
|
8
8
|
import { selectShouldPromptForOrganization } from "../../host/ui-slots.js";
|
|
9
9
|
import { selectIsCacheOnly } from "../../agents/redux/execution-system/conversations/conversations.selectors.js";
|
|
10
|
-
import { replaceAddressWithoutNavigating } from "
|
|
10
|
+
import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
|
|
11
11
|
import { describeLaunchError } from "./describe-launch-error.js";
|
|
12
12
|
import { selectOrganizationId, ensureOrganizationContext, isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
13
13
|
function initialRequest(start) {
|
|
@@ -37,7 +37,7 @@ const toSidebarItem = (c) => ({
|
|
|
37
37
|
status: c.status
|
|
38
38
|
});
|
|
39
39
|
const selectSidebarConversations = (state) => selectGlobalConversationList(state);
|
|
40
|
-
import { conversationTitleText } from "
|
|
40
|
+
import { conversationTitleText } from "@ai-matrx/content-ir/surfaces";
|
|
41
41
|
const GROUP_ORDER = ["Today", "Yesterday", "This Week", "This Month", "Older"];
|
|
42
42
|
function groupByTime(items) {
|
|
43
43
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -24,7 +24,7 @@ import { useComposerMode } from "../../../agents/components/inputs/smart-input/c
|
|
|
24
24
|
import { ProposedDirectivesZone } from "../../../host/ui-slots.js";
|
|
25
25
|
import { ServerOperationBanner } from "../../../agents/runtime-reconnect/ServerOperationBanner.js";
|
|
26
26
|
import { pushAppHref } from "../../../host/ui-slots.js";
|
|
27
|
-
import { replaceAddressWithoutNavigating } from "
|
|
27
|
+
import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
|
|
28
28
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
29
29
|
function ChatConversationClient({
|
|
30
30
|
conversationId,
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
Save
|
|
14
14
|
} from "lucide-react";
|
|
15
15
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
16
|
-
import
|
|
16
|
+
import MarkdownStream from "../../../ui/markdown-stream/MarkdownStream.js";
|
|
17
17
|
import AudioOutputBlockSkeleton from "../../../ui/AudioOutputBlockSkeleton.js";
|
|
18
18
|
import { useDomCapturePrint } from "../../../conversation/hooks/useDomCapturePrint.js";
|
|
19
19
|
import { useAppSelector, useAppDispatch } from "../../../store/hooks.js";
|
|
@@ -12,7 +12,7 @@ import { toast } from "../../host/notify.js";
|
|
|
12
12
|
import { isNotAuthenticatedError } from "../../host/identity.js";
|
|
13
13
|
import { isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
14
14
|
import { DEFAULT_AGENT_ID } from "../components/agent/local-agents.js";
|
|
15
|
-
import { replaceAddressWithoutNavigating } from "
|
|
15
|
+
import { replaceAddressWithoutNavigating } from "@ai-matrx/rich-content/utils/addressWithoutNavigating";
|
|
16
16
|
import { ensureAgentCatalog, isAgentCatalogStale } from "../../agents/identity/agent-identity.js";
|
|
17
17
|
function parseChatUrl(pathname, searchParams) {
|
|
18
18
|
const agentPathMatch = pathname.match(/\/demos\/chat\/a\/([^/?]+)/);
|
|
@@ -13,7 +13,7 @@ import {
|
|
|
13
13
|
Save
|
|
14
14
|
} from "lucide-react";
|
|
15
15
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
16
|
-
import
|
|
16
|
+
import MarkdownStream from "../ui/markdown-stream/MarkdownStream.js";
|
|
17
17
|
import AudioOutputBlockSkeleton from "../ui/AudioOutputBlockSkeleton.js";
|
|
18
18
|
import { useDomCapturePrint } from "../conversation/hooks/useDomCapturePrint.js";
|
|
19
19
|
import { useAppSelector, useAppDispatch } from "../store/hooks.js";
|
package/dist/host/configure.js
CHANGED
|
@@ -7,7 +7,12 @@ import {
|
|
|
7
7
|
createLogClientErrorDiagnostics,
|
|
8
8
|
isChatSourceApp
|
|
9
9
|
} from "./defaults/diagnostics.js";
|
|
10
|
-
import {
|
|
10
|
+
import {
|
|
11
|
+
createDbIdentity,
|
|
12
|
+
createTokenIdentity,
|
|
13
|
+
createUnreadableTokenIdentity,
|
|
14
|
+
isTokenOnlyClient
|
|
15
|
+
} from "./defaults/identity.js";
|
|
11
16
|
import { createStoredOrg } from "./defaults/org.js";
|
|
12
17
|
import { createDefaultServer } from "./defaults/server.js";
|
|
13
18
|
import { createDefaultServerApi } from "./defaults/server-api.js";
|
|
@@ -45,7 +50,8 @@ const PORTS = [
|
|
|
45
50
|
"feedback",
|
|
46
51
|
"routes",
|
|
47
52
|
"canvas",
|
|
48
|
-
"routing"
|
|
53
|
+
"routing",
|
|
54
|
+
"deviceTools"
|
|
49
55
|
];
|
|
50
56
|
const ANY_ROUTING = Object.freeze({ policy: () => "any" });
|
|
51
57
|
const EMPTY_REGISTRATIONS = Object.freeze({});
|
|
@@ -55,7 +61,7 @@ function assertDb(host) {
|
|
|
55
61
|
if (host?.source) return;
|
|
56
62
|
throw new ChatHostInvalidError("`db` is missing (pass `db`, or a message `source`)");
|
|
57
63
|
}
|
|
58
|
-
if (typeof db.rpc !== "function" || typeof db.from !== "function" || !db.auth) {
|
|
64
|
+
if (typeof db.rpc !== "function" || typeof db.from !== "function" || !isTokenOnlyClient(db) && !db.auth) {
|
|
59
65
|
throw new ChatHostInvalidError(
|
|
60
66
|
"`db` is not a Supabase client (no auth/rpc/from)"
|
|
61
67
|
);
|
|
@@ -82,9 +88,12 @@ function resolveChatHost(host) {
|
|
|
82
88
|
PORTS.filter((name) => host[name] !== void 0)
|
|
83
89
|
);
|
|
84
90
|
const ref = {};
|
|
85
|
-
const diagnostics = host.diagnostics ?? (hasDatabase ? createLogClientErrorDiagnostics(db, {
|
|
91
|
+
const diagnostics = host.diagnostics ?? (hasDatabase ? createLogClientErrorDiagnostics(db, {
|
|
92
|
+
sourceApp: host.sourceApp,
|
|
93
|
+
signedIn: async () => await ref.identity.getAccessToken() !== null
|
|
94
|
+
}) : createConsoleDiagnostics());
|
|
86
95
|
const notify = host.notify ?? createDomNotifier();
|
|
87
|
-
const identity = host.identity ?? (hasDatabase ?
|
|
96
|
+
const identity = host.identity ?? (!hasDatabase ? SOURCE_ONLY_IDENTITY : host.accessToken ? createTokenIdentity(db, host.accessToken, () => ref.diagnostics) : isTokenOnlyClient(db) ? createUnreadableTokenIdentity((message) => announceOnce("identity:token-only-no-function", message)) : createDbIdentity(db, () => ref.diagnostics));
|
|
88
97
|
const org = host.org ?? createStoredOrg(
|
|
89
98
|
() => ref.notify,
|
|
90
99
|
() => ref.diagnostics
|
|
@@ -130,6 +139,7 @@ function resolveChatHost(host) {
|
|
|
130
139
|
routes: { ...DEFAULT_CHAT_ROUTES, ...host.routes },
|
|
131
140
|
canvas: host.canvas ?? createUnhostedCanvas(() => ref.diagnostics),
|
|
132
141
|
routing: host.routing ?? ANY_ROUTING,
|
|
142
|
+
deviceTools: host.deviceTools ?? null,
|
|
133
143
|
overridden
|
|
134
144
|
});
|
|
135
145
|
return ref;
|
package/dist/host/contract.d.ts
CHANGED
|
@@ -738,6 +738,34 @@ export interface ChatAppIdentity {
|
|
|
738
738
|
* `"local-only"` (confidential) conversation refuses every target but the Matrx Local engine on this
|
|
739
739
|
* computer, loudly, before a byte leaves the machine. Default: `"any"` for every conversation.
|
|
740
740
|
*/
|
|
741
|
+
/** What a device-tool run answered (the same shape the browser-extension bridge answers). */
|
|
742
|
+
export type ChatDeviceToolInvocation = {
|
|
743
|
+
handled: false;
|
|
744
|
+
reason: string;
|
|
745
|
+
} | {
|
|
746
|
+
handled: true;
|
|
747
|
+
ok: true;
|
|
748
|
+
output: Record<string, unknown>;
|
|
749
|
+
} | {
|
|
750
|
+
handled: true;
|
|
751
|
+
ok: false;
|
|
752
|
+
error: string;
|
|
753
|
+
};
|
|
754
|
+
/**
|
|
755
|
+
* Tools that run ON THIS DEVICE for a cloud agent (lanes/agents-chat-proposal.md W0(c)): the
|
|
756
|
+
* browser tools when the chat runs inside Matrx Extend, local machine tools in a desktop host. The
|
|
757
|
+
* package owns the whole loop around them — the delegated call's lifecycle, the durable result
|
|
758
|
+
* submit with retry, and the resume (`surfaceDelegatedToolCall` → `submitToolResult`); the host
|
|
759
|
+
* only executes. `handled: false` = "not a tool this device owns" (the model is told, never a
|
|
760
|
+
* wedge). Absent: delegated device tools go to the installed browser extension through the server
|
|
761
|
+
* port (`invokeMatrxExtendTool`), as on the web.
|
|
762
|
+
*/
|
|
763
|
+
export interface ChatDeviceToolsPort {
|
|
764
|
+
invoke(toolName: string, args: Record<string, unknown>, context: {
|
|
765
|
+
conversationId: string;
|
|
766
|
+
callId: string;
|
|
767
|
+
}): Promise<ChatDeviceToolInvocation>;
|
|
768
|
+
}
|
|
741
769
|
export interface ChatRoutingPort {
|
|
742
770
|
policy(conversationId: string): ChatRoutingPolicy;
|
|
743
771
|
}
|
|
@@ -767,7 +795,16 @@ export interface ChatHost {
|
|
|
767
795
|
* that is not matrx-frontend never labels its rows as the main app's.
|
|
768
796
|
*/
|
|
769
797
|
app?: ChatAppIdentity;
|
|
770
|
-
/**
|
|
798
|
+
/**
|
|
799
|
+
* The token function a token-only client was built with (supabase-js `accessToken` option, the
|
|
800
|
+
* matrx-local custodian shape): pass the SAME function here and the default identity reads who is
|
|
801
|
+
* signed in from it. A token-only `db` without it is signed out, announced once with this remedy.
|
|
802
|
+
*/
|
|
803
|
+
accessToken?: () => Promise<string | null>;
|
|
804
|
+
/**
|
|
805
|
+
* Default: from db.auth (getSession + onAuthStateChange); for a token-only `db`, from
|
|
806
|
+
* `accessToken`. Admin level from admin.admins either way.
|
|
807
|
+
*/
|
|
771
808
|
identity?: ChatIdentityPort;
|
|
772
809
|
/** Default: no active org; `require` refuses loudly (never auto-picks). */
|
|
773
810
|
org?: ChatOrgPort;
|
|
@@ -803,8 +840,10 @@ export interface ChatHost {
|
|
|
803
840
|
canvas?: ChatCanvasPort;
|
|
804
841
|
/** Default: every conversation may go to any target (`"any"`). */
|
|
805
842
|
routing?: ChatRoutingPort;
|
|
843
|
+
/** Default: none — delegated device tools go to the browser extension via the server port. */
|
|
844
|
+
deviceTools?: ChatDeviceToolsPort;
|
|
806
845
|
}
|
|
807
|
-
export type ChatPortName = "identity" | "org" | "server" | "notify" | "diagnostics" | "prefs" | "navigation" | "windows" | "catalog" | "registry" | "chrome" | "feedback" | "routes" | "canvas" | "routing";
|
|
846
|
+
export type ChatPortName = "identity" | "org" | "server" | "notify" | "diagnostics" | "prefs" | "navigation" | "windows" | "catalog" | "registry" | "chrome" | "feedback" | "routes" | "canvas" | "routing" | "deviceTools";
|
|
808
847
|
/** Every port present. `overridden` names the ports the host supplied itself. */
|
|
809
848
|
export interface ResolvedChatHost {
|
|
810
849
|
/** The host's client, or the no-database stand-in when it gave only a `source`. */
|
|
@@ -831,5 +870,7 @@ export interface ResolvedChatHost {
|
|
|
831
870
|
routes: ChatRoutes;
|
|
832
871
|
canvas: ChatCanvasPort;
|
|
833
872
|
routing: ChatRoutingPort;
|
|
873
|
+
/** The host's on-device tool executor, or null. */
|
|
874
|
+
deviceTools: ChatDeviceToolsPort | null;
|
|
834
875
|
overridden: ReadonlySet<ChatPortName>;
|
|
835
876
|
}
|
package/dist/host/db.js
CHANGED
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
AuthSessionMissingError
|
|
4
4
|
} from "@supabase/supabase-js";
|
|
5
5
|
import { getChatHost } from "./configure.js";
|
|
6
|
+
import { decodeTokenClaims, isTokenOnlyClient } from "./defaults/identity.js";
|
|
6
7
|
function createClient() {
|
|
7
8
|
return getChatHost().db;
|
|
8
9
|
}
|
|
@@ -35,6 +36,11 @@ function userFromClaims(claims) {
|
|
|
35
36
|
};
|
|
36
37
|
}
|
|
37
38
|
async function getClaimsUser(client, jwt) {
|
|
39
|
+
if (isTokenOnlyClient(client)) {
|
|
40
|
+
const token = jwt ?? await getChatHost().identity.getAccessToken().catch(() => null);
|
|
41
|
+
const claims = token ? decodeTokenClaims(token) : null;
|
|
42
|
+
return { data: { user: userFromClaims(claims ?? void 0) }, error: null };
|
|
43
|
+
}
|
|
38
44
|
const { data, error } = await client.auth.getClaims(jwt);
|
|
39
45
|
if (error) {
|
|
40
46
|
if (isSignedOutError(error)) return { data: { user: null }, error: null };
|
|
@@ -27,6 +27,11 @@ export interface LogClientErrorDiagnosticsOptions {
|
|
|
27
27
|
/** Default: `process.env.NODE_ENV === "production"`. */
|
|
28
28
|
persist?: boolean;
|
|
29
29
|
flushDelayMs?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Is someone signed in? The resolver passes the identity port's answer, so a token-only client
|
|
32
|
+
* works. Default (a db with an auth-js session): `db.auth.getSession()`.
|
|
33
|
+
*/
|
|
34
|
+
signedIn?: () => Promise<boolean>;
|
|
30
35
|
}
|
|
31
36
|
export declare function isChatSourceApp(value: unknown): value is ChatSourceApp;
|
|
32
37
|
export declare function createLogClientErrorDiagnostics(db: ChatDb, options: LogClientErrorDiagnosticsOptions): ChatDiagnosticsPort;
|
|
@@ -59,8 +59,7 @@ function createLogClientErrorDiagnostics(db, options) {
|
|
|
59
59
|
if (queue.length === 0) return;
|
|
60
60
|
let signedIn = false;
|
|
61
61
|
try {
|
|
62
|
-
|
|
63
|
-
signedIn = Boolean(data.session?.user);
|
|
62
|
+
signedIn = options.signedIn ? await options.signedIn() : Boolean((await db.auth.getSession()).data.session?.user);
|
|
64
63
|
} catch {
|
|
65
64
|
signedIn = false;
|
|
66
65
|
}
|
|
@@ -3,6 +3,32 @@
|
|
|
3
3
|
* admin level from `admin.admins` (RLS: a person reads their own row). Starts
|
|
4
4
|
* on first use, never at import, so SSR and tests that never ask pay nothing.
|
|
5
5
|
*/
|
|
6
|
+
import type { User } from "@supabase/supabase-js";
|
|
6
7
|
import type { ChatDb, ChatDiagnosticsPort, ChatIdentity, ChatIdentityPort } from "../contract.js";
|
|
7
8
|
export declare const SIGNED_OUT_IDENTITY: ChatIdentity;
|
|
8
9
|
export declare function createDbIdentity(db: ChatDb, diagnostics: () => ChatDiagnosticsPort): ChatIdentityPort;
|
|
10
|
+
/**
|
|
11
|
+
* Is this a supabase-js client built with the `accessToken` option? Such a client has no auth-js
|
|
12
|
+
* session: touching `db.auth` throws by construction (matrx-local's custodian client is one). The
|
|
13
|
+
* probe reads the property inside a try, so it never throws itself.
|
|
14
|
+
*/
|
|
15
|
+
export declare function isTokenOnlyClient(db: unknown): boolean;
|
|
16
|
+
/** A JWT's payload as an object (no verification — routing metadata only). */
|
|
17
|
+
export declare function decodeTokenClaims(token: string): Record<string, unknown> | null;
|
|
18
|
+
/**
|
|
19
|
+
* The person a token names, read from its claims — routing metadata, not verification (the
|
|
20
|
+
* server and RLS verify every call that token makes). `null` when the token names nobody.
|
|
21
|
+
*/
|
|
22
|
+
export declare function userFromAccessToken(token: string | null): User | null;
|
|
23
|
+
/**
|
|
24
|
+
* Identity for a token-only client: the host hands the same `accessToken` function it gave
|
|
25
|
+
* supabase-js, and the package reads who is signed in from it. Every `getAccessToken()` re-reads
|
|
26
|
+
* the token, so a refresh or an account switch reaches the snapshot (and its subscribers) the next
|
|
27
|
+
* time anything asks; admin level is read through `db` exactly like the session default.
|
|
28
|
+
*/
|
|
29
|
+
export declare function createTokenIdentity(db: ChatDb, getToken: () => Promise<string | null>, diagnostics: () => ChatDiagnosticsPort): ChatIdentityPort;
|
|
30
|
+
/**
|
|
31
|
+
* A token-only client with no `accessToken` function: nobody can be read. Signed out and settled
|
|
32
|
+
* (never a forever-loading screen), announced once with the remedy.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createUnreadableTokenIdentity(announce: (message: string) => void): ChatIdentityPort;
|
|
@@ -113,7 +113,139 @@ function createDbIdentity(db, diagnostics) {
|
|
|
113
113
|
}
|
|
114
114
|
};
|
|
115
115
|
}
|
|
116
|
+
function isTokenOnlyClient(db) {
|
|
117
|
+
if (db === null || typeof db !== "object") return false;
|
|
118
|
+
try {
|
|
119
|
+
const auth = db.auth;
|
|
120
|
+
if (!auth) return true;
|
|
121
|
+
void auth.getSession;
|
|
122
|
+
return false;
|
|
123
|
+
} catch {
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
function decodeTokenClaims(token) {
|
|
128
|
+
const payload = token.split(".")[1];
|
|
129
|
+
if (!payload) return null;
|
|
130
|
+
try {
|
|
131
|
+
const normalized = payload.replace(/-/g, "+").replace(/_/g, "/");
|
|
132
|
+
const padded = normalized + "=".repeat((4 - normalized.length % 4) % 4);
|
|
133
|
+
const parsed = JSON.parse(
|
|
134
|
+
typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("utf8")
|
|
135
|
+
);
|
|
136
|
+
return parsed !== null && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : null;
|
|
137
|
+
} catch {
|
|
138
|
+
return null;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
function userFromAccessToken(token) {
|
|
142
|
+
if (!token) return null;
|
|
143
|
+
const claims = decodeTokenClaims(token);
|
|
144
|
+
if (!claims || typeof claims.sub !== "string" || !claims.sub) return null;
|
|
145
|
+
const meta = claims.user_metadata;
|
|
146
|
+
const appMeta = claims.app_metadata;
|
|
147
|
+
return {
|
|
148
|
+
id: claims.sub,
|
|
149
|
+
email: typeof claims.email === "string" ? claims.email : void 0,
|
|
150
|
+
user_metadata: meta !== null && typeof meta === "object" ? meta : {},
|
|
151
|
+
app_metadata: appMeta !== null && typeof appMeta === "object" ? appMeta : {},
|
|
152
|
+
aud: typeof claims.aud === "string" ? claims.aud : "authenticated",
|
|
153
|
+
created_at: ""
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function createTokenIdentity(db, getToken, diagnostics) {
|
|
157
|
+
let snapshot = SIGNED_OUT_IDENTITY;
|
|
158
|
+
let started = false;
|
|
159
|
+
let adminFor = null;
|
|
160
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
161
|
+
function publish(next) {
|
|
162
|
+
if (snapshot.userId === next.userId && snapshot.accessToken === next.accessToken && snapshot.adminLevel === next.adminLevel && snapshot.authReady === next.authReady) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
snapshot = next;
|
|
166
|
+
for (const listener of listeners) listener();
|
|
167
|
+
}
|
|
168
|
+
async function readAdminLevel(userId) {
|
|
169
|
+
try {
|
|
170
|
+
const { data, error } = await db.schema("admin").from("admins").select("level").eq("user_id", userId).maybeSingle();
|
|
171
|
+
if (error) throw error;
|
|
172
|
+
const level = data?.level;
|
|
173
|
+
return ADMIN_LEVELS.includes(level) ? level : null;
|
|
174
|
+
} catch (error) {
|
|
175
|
+
diagnostics().capture(error, { area: "identity", code: "admin-level-unreadable" });
|
|
176
|
+
return null;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async function refresh() {
|
|
180
|
+
let token;
|
|
181
|
+
try {
|
|
182
|
+
token = await getToken();
|
|
183
|
+
} catch (error) {
|
|
184
|
+
diagnostics().capture(error, { area: "identity", code: "access-token-unreadable" });
|
|
185
|
+
token = null;
|
|
186
|
+
}
|
|
187
|
+
const user = userFromAccessToken(token);
|
|
188
|
+
const level = user && user.id === snapshot.userId ? snapshot.adminLevel : null;
|
|
189
|
+
publish(identityFromUser(user, level, user ? token : null));
|
|
190
|
+
if (user && adminFor !== user.id) {
|
|
191
|
+
adminFor = user.id;
|
|
192
|
+
const read = await readAdminLevel(user.id);
|
|
193
|
+
if (snapshot.userId === user.id) publish(identityFromUser(user, read, snapshot.accessToken));
|
|
194
|
+
}
|
|
195
|
+
return user ? token : null;
|
|
196
|
+
}
|
|
197
|
+
function start() {
|
|
198
|
+
if (started) return;
|
|
199
|
+
started = true;
|
|
200
|
+
void refresh();
|
|
201
|
+
}
|
|
202
|
+
return {
|
|
203
|
+
current() {
|
|
204
|
+
start();
|
|
205
|
+
return snapshot;
|
|
206
|
+
},
|
|
207
|
+
subscribe(listener) {
|
|
208
|
+
start();
|
|
209
|
+
listeners.add(listener);
|
|
210
|
+
return () => {
|
|
211
|
+
listeners.delete(listener);
|
|
212
|
+
};
|
|
213
|
+
},
|
|
214
|
+
getAccessToken: refresh
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
function createUnreadableTokenIdentity(announce) {
|
|
218
|
+
const value = Object.freeze({ ...SIGNED_OUT_IDENTITY, authReady: true });
|
|
219
|
+
let said = false;
|
|
220
|
+
const say = () => {
|
|
221
|
+
if (said) return;
|
|
222
|
+
said = true;
|
|
223
|
+
announce(
|
|
224
|
+
"This chat's database client was built with an access-token function, so the chat cannot read who is signed in. Pass the same function to the chat host as `accessToken`."
|
|
225
|
+
);
|
|
226
|
+
};
|
|
227
|
+
return {
|
|
228
|
+
current() {
|
|
229
|
+
say();
|
|
230
|
+
return value;
|
|
231
|
+
},
|
|
232
|
+
subscribe() {
|
|
233
|
+
say();
|
|
234
|
+
return () => {
|
|
235
|
+
};
|
|
236
|
+
},
|
|
237
|
+
async getAccessToken() {
|
|
238
|
+
say();
|
|
239
|
+
return null;
|
|
240
|
+
}
|
|
241
|
+
};
|
|
242
|
+
}
|
|
116
243
|
export {
|
|
117
244
|
SIGNED_OUT_IDENTITY,
|
|
118
|
-
createDbIdentity
|
|
245
|
+
createDbIdentity,
|
|
246
|
+
createTokenIdentity,
|
|
247
|
+
createUnreadableTokenIdentity,
|
|
248
|
+
decodeTokenClaims,
|
|
249
|
+
isTokenOnlyClient,
|
|
250
|
+
userFromAccessToken
|
|
119
251
|
};
|
package/dist/host/identity.d.ts
CHANGED
|
@@ -50,8 +50,25 @@ export declare function isNotAuthenticatedError(error: unknown): error is NotAut
|
|
|
50
50
|
/** The signed-in person's id; throws `NotAuthenticatedError` when nobody is. */
|
|
51
51
|
export declare function requireUserId(): string;
|
|
52
52
|
/**
|
|
53
|
-
*
|
|
54
|
-
*
|
|
53
|
+
* The signed-in person's access token, or null — THE one session read in the package. It goes
|
|
54
|
+
* through the host's identity port, so a session client (auth-js) and a token-only client
|
|
55
|
+
* (`ChatHost.accessToken`) answer the same way; nothing else in the package touches `db.auth`
|
|
56
|
+
* (guard: `host/__tests__/session-reads-go-through-the-identity-port.test.ts`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function readSessionToken(): Promise<string | null>;
|
|
59
|
+
/** `readSessionToken` in the structural shape `@ai-matrx/data`'s session retry reads. */
|
|
60
|
+
export declare const hostSessionSource: {
|
|
61
|
+
getSession(): Promise<{
|
|
62
|
+
data: {
|
|
63
|
+
session: {
|
|
64
|
+
access_token: string;
|
|
65
|
+
} | null;
|
|
66
|
+
};
|
|
67
|
+
error: null;
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Does this client carry a signed-in session? For skipping reads only a signed-in person can make;
|
|
55
72
|
* "no session" means an empty result, never a way around a reader a guest needs.
|
|
56
73
|
*/
|
|
57
74
|
export declare function hasBrowserSession(): Promise<boolean>;
|
package/dist/host/identity.js
CHANGED
|
@@ -40,11 +40,11 @@ function requireUserId() {
|
|
|
40
40
|
if (!id) throw new NotAuthenticatedError();
|
|
41
41
|
return id;
|
|
42
42
|
}
|
|
43
|
-
async function
|
|
44
|
-
if (!chatHostHasDatabase()) return
|
|
45
|
-
let
|
|
43
|
+
async function readSessionToken() {
|
|
44
|
+
if (!chatHostHasDatabase()) return null;
|
|
45
|
+
let host;
|
|
46
46
|
try {
|
|
47
|
-
|
|
47
|
+
host = getChatHost();
|
|
48
48
|
} catch (error) {
|
|
49
49
|
announceOnce(
|
|
50
50
|
"identity:no-host-session",
|
|
@@ -52,16 +52,22 @@ async function hasBrowserSession() {
|
|
|
52
52
|
error?.message ?? error
|
|
53
53
|
)}).`
|
|
54
54
|
);
|
|
55
|
-
return
|
|
55
|
+
return null;
|
|
56
56
|
}
|
|
57
57
|
try {
|
|
58
|
-
|
|
59
|
-
data: { session }
|
|
60
|
-
} = await db.auth.getSession();
|
|
61
|
-
return Boolean(session);
|
|
58
|
+
return await host.identity.getAccessToken();
|
|
62
59
|
} catch {
|
|
63
|
-
return
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
const hostSessionSource = {
|
|
64
|
+
async getSession() {
|
|
65
|
+
const token = await readSessionToken();
|
|
66
|
+
return { data: { session: token ? { access_token: token } : null }, error: null };
|
|
64
67
|
}
|
|
68
|
+
};
|
|
69
|
+
async function hasBrowserSession() {
|
|
70
|
+
return await readSessionToken() !== null;
|
|
65
71
|
}
|
|
66
72
|
async function isSignedOutVisitor() {
|
|
67
73
|
return !getUserId() && !await hasBrowserSession();
|
|
@@ -70,8 +76,10 @@ export {
|
|
|
70
76
|
NotAuthenticatedError,
|
|
71
77
|
getUserId,
|
|
72
78
|
hasBrowserSession,
|
|
79
|
+
hostSessionSource,
|
|
73
80
|
isNotAuthenticatedError,
|
|
74
81
|
isSignedOutVisitor,
|
|
82
|
+
readSessionToken,
|
|
75
83
|
requireUserId,
|
|
76
84
|
selectAccessToken,
|
|
77
85
|
selectActiveUserName,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { createSessionRetry } from "@ai-matrx/data/db";
|
|
2
|
-
import {
|
|
2
|
+
import { hostSessionSource } from "./identity.js";
|
|
3
3
|
import {
|
|
4
4
|
isMissingSessionError,
|
|
5
5
|
SessionUnavailableError
|
|
6
6
|
} from "@ai-matrx/data/db";
|
|
7
7
|
const runWithSessionRetry = createSessionRetry({
|
|
8
|
-
auth:
|
|
8
|
+
auth: hostSessionSource
|
|
9
9
|
});
|
|
10
10
|
export {
|
|
11
11
|
SessionUnavailableError,
|
|
@@ -5,6 +5,6 @@
|
|
|
5
5
|
* keys the client run path honours. Field by field, no casts; unknown keys
|
|
6
6
|
* are dropped LOUDLY (the server's apply_overrides stays the authority).
|
|
7
7
|
*/
|
|
8
|
-
import type { JsonObject } from "
|
|
8
|
+
import type { JsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
9
9
|
import type { FeLlmParams } from "../agents/types/agent-api-types.js";
|
|
10
10
|
export declare function toLlmParams(obj: JsonObject): Partial<FeLlmParams>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createClient } from "../host/db.js";
|
|
2
|
-
import { isJsonObject } from "
|
|
2
|
+
import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
3
3
|
import { hasBrowserSession } from "../host/identity.js";
|
|
4
4
|
function outputSchemaKeys(outputSchema) {
|
|
5
5
|
if (!isJsonObject(outputSchema)) return /* @__PURE__ */ new Set();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { FeLlmParams } from "../agents/types/agent-api-types.js";
|
|
2
2
|
import { type OrganizationAdmission } from "../host/server/organization-admission.js";
|
|
3
3
|
import { type MandateContract } from "@ai-matrx/agents/mandates";
|
|
4
|
-
import type { JsonObject } from "
|
|
4
|
+
import type { JsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
5
5
|
import type { AnyMandateKey } from "@ai-matrx/agents/mandates";
|
|
6
6
|
import { type BindingPresentation } from "../ui/treatment-shape.js";
|
|
7
7
|
export interface ResolvedMandate {
|
package/dist/mandates/service.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { createClient } from "../host/db.js";
|
|
3
3
|
import { getClaimsUser } from "../host/db.js";
|
|
4
|
-
import { isJsonObject } from "
|
|
4
|
+
import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
5
5
|
import { recordUnavailable } from "../host/diagnostics.js";
|
|
6
6
|
import { apiGet, buildPath } from "../host/server/typed-client.js";
|
|
7
7
|
import { BackendApiError } from "@ai-matrx/agents/matrx";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { isJsonObject } from "
|
|
2
|
+
import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
3
3
|
import { usableServerNotes } from "../ui/usable-server-notes.js";
|
|
4
4
|
function readMandateRunHolder(result) {
|
|
5
5
|
if (!isJsonObject(result)) {
|
|
@@ -26,7 +26,7 @@ import { useAppSelector as useSelector } from "../../store/hooks.js";
|
|
|
26
26
|
import { selectIsAuthenticated } from "../../host/identity.js";
|
|
27
27
|
import { useAppDispatch } from "../../store/hooks.js";
|
|
28
28
|
import { openOverlay, CHAT_WINDOWS } from "../../host/windows.js";
|
|
29
|
-
import { kindTextToMarkdown } from "
|
|
29
|
+
import { kindTextToMarkdown } from "@ai-matrx/content-ir/surfaces";
|
|
30
30
|
import { removeCodeSpans, replaceFences } from "@ai-matrx/content-ir/source";
|
|
31
31
|
import { selectOrganizationId, ensureOrganizationContext, isOrganizationSelectionCancelled } from "../../host/org.js";
|
|
32
32
|
import { downloadFile } from "@ai-matrx/kit/download";
|
|
@@ -16,6 +16,7 @@ import { ensureOrgAvailability } from "../../host/ui-slots.js";
|
|
|
16
16
|
import { assertMappingsAreAnswerable } from "../../ui/mandates-storage/provision-shapes.js";
|
|
17
17
|
import { ensureOrgId } from "../../host/org.js";
|
|
18
18
|
import { readProjectScopeOrganizationId } from "../../host/ui-slots.js";
|
|
19
|
+
import { hasBrowserSession } from "../../host/identity.js";
|
|
19
20
|
function tierFromScope(scope) {
|
|
20
21
|
if (scope.userId) return "user";
|
|
21
22
|
if (scope.organizationId) return "org";
|
|
@@ -359,10 +360,7 @@ async function listAgentSurfaceBindings(agentId) {
|
|
|
359
360
|
async function fetchSurfaceBindingLayers(agentId, surfaceName) {
|
|
360
361
|
const chain = [...getSurfaceAncestry(surfaceName), surfaceName];
|
|
361
362
|
const sb = createClient();
|
|
362
|
-
|
|
363
|
-
data: { session }
|
|
364
|
-
} = await sb.auth.getSession();
|
|
365
|
-
if (!session) return [];
|
|
363
|
+
if (!await hasBrowserSession()) return [];
|
|
366
364
|
const { data, error } = await sb.schema("agent").from("menu_surface").select(MENU_SURFACE_COLUMNS).eq("agent_id", agentId).in("surface_name", chain);
|
|
367
365
|
if (error) throw error;
|
|
368
366
|
const rows = (data ?? []).map(fromRow).filter(
|
|
@@ -3,7 +3,7 @@ import { storedMandateKey } from "@ai-matrx/agents/mandates";
|
|
|
3
3
|
import { createClient } from "../../host/db.js";
|
|
4
4
|
import { writeOne } from "@ai-matrx/data/db";
|
|
5
5
|
import { getClaimsUser } from "../../host/db.js";
|
|
6
|
-
import { isJsonObject } from "
|
|
6
|
+
import { isJsonObject } from "@ai-matrx/rich-content/utils/json";
|
|
7
7
|
import { fetchMandatePins } from "../../mandates/service.js";
|
|
8
8
|
import {
|
|
9
9
|
getNamespaceHandler,
|
|
@@ -4,7 +4,7 @@ import { useEffect, useState } from "react";
|
|
|
4
4
|
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
5
5
|
import { cn } from "@ai-matrx/design-system";
|
|
6
6
|
import { useAppSelector } from "../../store/hooks.js";
|
|
7
|
-
import { ShimmerText } from "
|
|
7
|
+
import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
|
|
8
8
|
import { getToolDisplayName } from "../registry/registry.js";
|
|
9
9
|
import { DIFF_START_OPEN_KNOB, readSurfaceWrite } from "../surface-write/readSurfaceWrite.js";
|
|
10
10
|
import { holdsADecision } from "./holdsADecision.js";
|
|
@@ -11,7 +11,7 @@ import { cn } from "@ai-matrx/design-system";
|
|
|
11
11
|
import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
|
|
12
12
|
import { smartExecute } from "../../agents/redux/execution-system/thunks/smart-execute.thunk.js";
|
|
13
13
|
import { openOverlay, CHAT_WINDOWS } from "../../host/windows.js";
|
|
14
|
-
import { ShimmerText } from "
|
|
14
|
+
import { ShimmerText } from "@ai-matrx/rich-content/utils/lifted/ShimmerText";
|
|
15
15
|
import {
|
|
16
16
|
getInlineRenderer,
|
|
17
17
|
getToolDisplayName,
|