@ai-matrx/chat 0.4.0 → 0.4.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 +26 -0
- package/dist/agents/addressing/useAgentHref.js +4 -1
- package/dist/agents/api/submit-tool-results.js +11 -1
- package/dist/agents/components/chat/useCanvasScopedToConversation.js +1 -1
- package/dist/agents/components/messages-display/AgentConversationDisplay.js +4 -1
- package/dist/agents/components/run-controls/panels/shared.d.ts +1 -0
- package/dist/agents/components/shared/AgentConversationColumn.js +3 -2
- package/dist/agents/components/working-document/workingDocumentSurface.d.ts +1 -1
- package/dist/agents/identity/model-catalog.js +5 -3
- package/dist/agents/redux/agent-definition/selectors.d.ts +237 -0
- package/dist/agents/redux/agent-settings/selectors.d.ts +12 -0
- package/dist/agents/redux/agent-shortcut-categories/selectors.d.ts +50 -0
- package/dist/agents/redux/agent-shortcuts/selectors.d.ts +147 -0
- package/dist/agents/redux/conversation-history/selectors.d.ts +16 -0
- package/dist/agents/redux/conversation-list/conversation-list.selectors.d.ts +2 -0
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.d.ts +54 -0
- package/dist/agents/redux/execution-system/context-state/context-state.selectors.d.ts +14 -0
- package/dist/agents/redux/execution-system/conversations/conversations.selectors.d.ts +5 -0
- package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.d.ts +12 -0
- package/dist/agents/redux/execution-system/host-conversations/conversation-abilities.js +25 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.d.ts +50 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversation.thunks.js +367 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.d.ts +28 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.selectors.js +41 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.d.ts +43 -0
- package/dist/agents/redux/execution-system/host-conversations/host-conversations.slice.js +38 -0
- package/dist/agents/redux/execution-system/host-conversations/source-registry.d.ts +9 -0
- package/dist/agents/redux/execution-system/host-conversations/source-registry.js +15 -0
- package/dist/agents/redux/execution-system/host-conversations/useHostConversation.d.ts +4 -0
- package/dist/agents/redux/execution-system/host-conversations/useHostConversation.js +24 -0
- package/dist/agents/redux/execution-system/instance-context/instance-context.selectors.d.ts +3 -0
- package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.d.ts +22 -0
- package/dist/agents/redux/execution-system/instance-resources/default-remark-durability.js +164 -0
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.d.ts +8 -0
- package/dist/agents/redux/execution-system/instance-ui-state/instance-ui-state.selectors.d.ts +5 -0
- package/dist/agents/redux/execution-system/instance-user-input/composer-draft-store.js +20 -0
- package/dist/agents/redux/execution-system/instance-user-input/useComposerDraftRestore.js +2 -1
- package/dist/agents/redux/execution-system/instance-variable-values/instance-variable-values.selectors.d.ts +7 -0
- package/dist/agents/redux/execution-system/messages/messages.selectors.d.ts +1 -0
- package/dist/agents/redux/execution-system/observability/observability.selectors.d.ts +7 -0
- package/dist/agents/redux/execution-system/observational-memory/observational-memory.selectors.d.ts +1 -0
- package/dist/agents/redux/execution-system/selectors/aggregate.selectors.d.ts +14 -0
- package/dist/agents/redux/execution-system/thunks/execute-instance.thunk.js +2 -1
- package/dist/agents/redux/execution-system/thunks/execute-manual-instance.thunk.js +2 -1
- package/dist/agents/redux/execution-system/thunks/load-conversation.thunk.js +6 -0
- package/dist/agents/redux/execution-system/thunks/load-older-messages.thunk.js +12 -0
- package/dist/agents/redux/execution-system/thunks/process-stream.js +5 -3
- package/dist/agents/redux/execution-system/thunks/resolve-base-url.js +1 -1
- package/dist/agents/redux/execution-system/thunks/smart-execute.thunk.js +43 -0
- package/dist/agents/redux/execution-system/utils/continuation-body.d.ts +1 -0
- package/dist/agents/redux/execution-system/utils/continuation-body.js +2 -1
- package/dist/agents/redux/proposed-directives/proposedDirectivesSlice.d.ts +1 -0
- package/dist/agents/redux/tools/tools.selectors.d.ts +1 -0
- package/dist/agents/resources/default-picker-items.d.ts +17 -0
- package/dist/agents/resources/default-picker-items.js +48 -0
- package/dist/agents/types/instance.types.d.ts +2 -1
- package/dist/agents/ui-first-tools/redux/agent-lists.selectors.d.ts +2 -0
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/sidebar/SidebarUserFooter.js +1 -1
- package/dist/host/app-identity.d.ts +20 -0
- package/dist/host/app-identity.js +21 -0
- package/dist/host/bare-host-chrome.d.ts +14 -0
- package/dist/host/bare-host-chrome.js +44 -0
- package/dist/host/configure.d.ts +9 -1
- package/dist/host/configure.js +44 -8
- package/dist/host/content-ir-slots.d.ts +5 -1
- package/dist/host/content-ir-slots.js +5 -1
- package/dist/host/contract.d.ts +39 -2
- package/dist/host/db-types.d.ts +99 -1
- package/dist/host/defaults/navigation-hooks.d.ts +2 -0
- package/dist/host/defaults/navigation-hooks.js +7 -1
- package/dist/host/defaults/navigation.d.ts +4 -3
- package/dist/host/defaults/navigation.js +38 -7
- package/dist/host/defaults/org.d.ts +12 -4
- package/dist/host/defaults/org.js +39 -1
- package/dist/host/defaults/workspace-gate.d.ts +16 -0
- package/dist/host/defaults/workspace-gate.js +88 -0
- package/dist/host/diagnostics.d.ts +7 -2
- package/dist/host/diagnostics.js +6 -0
- package/dist/host/identity.js +2 -1
- package/dist/host/index.d.ts +5 -2
- package/dist/host/index.js +21 -1
- package/dist/host/no-database.d.ts +38 -0
- package/dist/host/no-database.js +107 -0
- package/dist/host/react.d.ts +1 -0
- package/dist/host/react.js +25 -2
- package/dist/host/registered-source.js +2 -2
- package/dist/host/source.d.ts +109 -0
- package/dist/host/source.js +86 -0
- package/dist/host/ui-slots.d.ts +8 -8
- package/dist/host/ui-slots.js +5 -3
- package/dist/mandates/useMandate.js +13 -0
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
- package/dist/store/create-chat-store.d.ts +4 -2
- package/dist/store/middlewares.d.ts +5 -0
- package/dist/store/slices.d.ts +1 -0
- package/dist/store/slices.js +4 -1
- package/dist/surfaces/redux/selectors.d.ts +2 -0
- package/dist/testing/turn-harness.d.ts +35 -0
- package/dist/testing/turn-harness.js +85 -0
- package/dist/tool-call-visualization/redux/selectors.d.ts +1 -0
- package/package.json +7 -4
package/dist/host/configure.d.ts
CHANGED
|
@@ -12,7 +12,9 @@
|
|
|
12
12
|
* port (identity → diagnostics, server → identity + org) always reaches the
|
|
13
13
|
* resolved one — the host's override when it gave one.
|
|
14
14
|
*/
|
|
15
|
-
import type { ChatHost, ChatRoutes, ResolvedChatHost } from "./contract.js";
|
|
15
|
+
import type { ChatAppIdentity, ChatHost, ChatRoutes, ResolvedChatHost } from "./contract.js";
|
|
16
|
+
/** What a host that names no `app` is called: the neutral registered producer, never matrx-frontend. */
|
|
17
|
+
export declare const DEFAULT_CHAT_APP: ChatAppIdentity;
|
|
16
18
|
/** The platform's production addresses — the default `routes`. */
|
|
17
19
|
export declare const DEFAULT_CHAT_ROUTES: ChatRoutes;
|
|
18
20
|
export declare function resolveChatHost(host: ChatHost): ResolvedChatHost;
|
|
@@ -22,6 +24,12 @@ export declare function configureChat(host: ChatHost): ResolvedChatHost;
|
|
|
22
24
|
export declare function onChatHostConfigured(listener: () => void): () => void;
|
|
23
25
|
/** The configured host. Throws `ChatHostNotConfiguredError` (with the remedy) when there is none. */
|
|
24
26
|
export declare function getChatHost(): ResolvedChatHost;
|
|
27
|
+
/**
|
|
28
|
+
* False when the configured host gave a message `source` and no `db` (the db is the stand-in).
|
|
29
|
+
* The branch every global database read takes FIRST (G-DOOR). Unconfigured: true — the read
|
|
30
|
+
* then fails loudly on the missing host, as before.
|
|
31
|
+
*/
|
|
32
|
+
export declare function chatHostHasDatabase(): boolean;
|
|
25
33
|
/** True once `configureChat` (or `<ChatProvider>` in a browser) has run. */
|
|
26
34
|
export declare function isChatHostConfigured(): boolean;
|
|
27
35
|
/** Test-only: forget the configured host. */
|
package/dist/host/configure.js
CHANGED
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
isChatSourceApp
|
|
9
9
|
} from "./defaults/diagnostics.js";
|
|
10
10
|
import { createDbIdentity } from "./defaults/identity.js";
|
|
11
|
-
import {
|
|
11
|
+
import { createStoredOrg } from "./defaults/org.js";
|
|
12
12
|
import { createDefaultServer } from "./defaults/server.js";
|
|
13
13
|
import { createDefaultServerApi } from "./defaults/server-api.js";
|
|
14
14
|
import { createDomNotifier } from "./defaults/notify.js";
|
|
@@ -19,6 +19,14 @@ import { createDbCatalogGetter } from "./defaults/catalog.js";
|
|
|
19
19
|
import { createDefaultChrome } from "./defaults/chrome.js";
|
|
20
20
|
import { createDbFeedback } from "./defaults/feedback.js";
|
|
21
21
|
import { createUnhostedCanvas } from "./defaults/canvas.js";
|
|
22
|
+
import { SIGNED_OUT_IDENTITY } from "./defaults/identity.js";
|
|
23
|
+
import {
|
|
24
|
+
NO_DATABASE_CODE_PREFIX,
|
|
25
|
+
createConsoleDiagnostics,
|
|
26
|
+
createNoDatabaseStandIn,
|
|
27
|
+
createNoServerApi
|
|
28
|
+
} from "./no-database.js";
|
|
29
|
+
const DEFAULT_CHAT_APP = Object.freeze({ sourceApp: "chat" });
|
|
22
30
|
const DEFAULT_CHAT_ROUTES = Object.freeze({
|
|
23
31
|
workflowStudio: "https://workflows.aimatrx.com"
|
|
24
32
|
});
|
|
@@ -41,24 +49,41 @@ const PORTS = [
|
|
|
41
49
|
const EMPTY_REGISTRATIONS = Object.freeze({});
|
|
42
50
|
function assertDb(host) {
|
|
43
51
|
const db = host?.db;
|
|
44
|
-
if (!db)
|
|
52
|
+
if (!db) {
|
|
53
|
+
if (host?.source) return;
|
|
54
|
+
throw new ChatHostInvalidError("`db` is missing (pass `db`, or a message `source`)");
|
|
55
|
+
}
|
|
45
56
|
if (typeof db.rpc !== "function" || typeof db.from !== "function" || !db.auth) {
|
|
46
57
|
throw new ChatHostInvalidError(
|
|
47
58
|
"`db` is not a Supabase client (no auth/rpc/from)"
|
|
48
59
|
);
|
|
49
60
|
}
|
|
50
61
|
}
|
|
62
|
+
const SOURCE_ONLY_IDENTITY = Object.freeze({
|
|
63
|
+
current: () => SOURCE_ONLY_IDENTITY_VALUE,
|
|
64
|
+
subscribe: () => () => {
|
|
65
|
+
},
|
|
66
|
+
getAccessToken: async () => null
|
|
67
|
+
});
|
|
68
|
+
const SOURCE_ONLY_IDENTITY_VALUE = Object.freeze({ ...SIGNED_OUT_IDENTITY, authReady: true });
|
|
51
69
|
function resolveChatHost(host) {
|
|
52
70
|
assertDb(host);
|
|
53
|
-
const
|
|
71
|
+
const hasDatabase = Boolean(host.db);
|
|
72
|
+
const reportNoDatabase = (feature) => {
|
|
73
|
+
ref.diagnostics.capture(new Error(`no database: ${feature}`), {
|
|
74
|
+
area: "host-source",
|
|
75
|
+
code: `${NO_DATABASE_CODE_PREFIX}${feature}`
|
|
76
|
+
});
|
|
77
|
+
};
|
|
78
|
+
const db = host.db ?? createNoDatabaseStandIn(reportNoDatabase);
|
|
54
79
|
const overridden = new Set(
|
|
55
80
|
PORTS.filter((name) => host[name] !== void 0)
|
|
56
81
|
);
|
|
57
82
|
const ref = {};
|
|
58
|
-
const diagnostics = host.diagnostics ?? createLogClientErrorDiagnostics(db, { sourceApp: host.sourceApp });
|
|
83
|
+
const diagnostics = host.diagnostics ?? (hasDatabase ? createLogClientErrorDiagnostics(db, { sourceApp: host.sourceApp }) : createConsoleDiagnostics());
|
|
59
84
|
const notify = host.notify ?? createDomNotifier();
|
|
60
|
-
const identity = host.identity ?? createDbIdentity(db, () => ref.diagnostics);
|
|
61
|
-
const org = host.org ??
|
|
85
|
+
const identity = host.identity ?? (hasDatabase ? createDbIdentity(db, () => ref.diagnostics) : SOURCE_ONLY_IDENTITY);
|
|
86
|
+
const org = host.org ?? createStoredOrg(
|
|
62
87
|
() => ref.notify,
|
|
63
88
|
() => ref.diagnostics
|
|
64
89
|
);
|
|
@@ -68,7 +93,10 @@ function resolveChatHost(host) {
|
|
|
68
93
|
);
|
|
69
94
|
const server = {
|
|
70
95
|
...serverPort,
|
|
71
|
-
api: serverPort.api ?? defaultServerApi(() => ref)
|
|
96
|
+
api: serverPort.api ?? (hasDatabase || host.server ? defaultServerApi(() => ref) : createNoServerApi(
|
|
97
|
+
reportNoDatabase,
|
|
98
|
+
defaultServerApi(() => ref)
|
|
99
|
+
))
|
|
72
100
|
};
|
|
73
101
|
const prefs = host.prefs ?? createWebPrefs();
|
|
74
102
|
const navigation = host.navigation ?? createWindowNavigation();
|
|
@@ -81,7 +109,10 @@ function resolveChatHost(host) {
|
|
|
81
109
|
);
|
|
82
110
|
Object.assign(ref, {
|
|
83
111
|
db,
|
|
112
|
+
hasDatabase,
|
|
113
|
+
source: host.source ?? null,
|
|
84
114
|
sourceApp: isChatSourceApp(host.sourceApp) ? host.sourceApp : null,
|
|
115
|
+
app: host.app ?? DEFAULT_CHAT_APP,
|
|
85
116
|
identity,
|
|
86
117
|
org,
|
|
87
118
|
server,
|
|
@@ -106,7 +137,7 @@ function defaultServerApi(host) {
|
|
|
106
137
|
let configured = null;
|
|
107
138
|
function configureChat(host) {
|
|
108
139
|
if (configured?.host === host) return configured.resolved;
|
|
109
|
-
if (configured && configured.host.db !== host.db) {
|
|
140
|
+
if (configured && configured.host.db && host.db && configured.host.db !== host.db) {
|
|
110
141
|
announceOnce(
|
|
111
142
|
"configure-replaced-db",
|
|
112
143
|
"configureChat was called again with a different `db`; the newest host replaces the first. Configure the chat host once per page."
|
|
@@ -131,6 +162,9 @@ function getChatHost() {
|
|
|
131
162
|
if (!configured) throw new ChatHostNotConfiguredError();
|
|
132
163
|
return configured.resolved;
|
|
133
164
|
}
|
|
165
|
+
function chatHostHasDatabase() {
|
|
166
|
+
return configured ? configured.resolved.hasDatabase : true;
|
|
167
|
+
}
|
|
134
168
|
function isChatHostConfigured() {
|
|
135
169
|
return configured !== null;
|
|
136
170
|
}
|
|
@@ -138,8 +172,10 @@ function _resetChatHostForTests() {
|
|
|
138
172
|
configured = null;
|
|
139
173
|
}
|
|
140
174
|
export {
|
|
175
|
+
DEFAULT_CHAT_APP,
|
|
141
176
|
DEFAULT_CHAT_ROUTES,
|
|
142
177
|
_resetChatHostForTests,
|
|
178
|
+
chatHostHasDatabase,
|
|
143
179
|
configureChat,
|
|
144
180
|
getChatHost,
|
|
145
181
|
isChatHostConfigured,
|
|
@@ -183,7 +183,11 @@ export declare const componentRegistry: ContentIrComponentRegistryPort;
|
|
|
183
183
|
export declare const contentIrKindValidator: () => KindValidator;
|
|
184
184
|
/** A host with no progress adapter promotes nothing: the event keeps only its ordinary typed data. */
|
|
185
185
|
export declare const progressDataRenderBlock: (data: unknown, eventIndex: number, blockIndex: number) => RenderBlockPayload | null;
|
|
186
|
-
/**
|
|
186
|
+
/**
|
|
187
|
+
* The classifier primitives ARE the block classifier, so a bare host gets the real ones from
|
|
188
|
+
* `@ai-matrx/rich-content` (the same module matrx-frontend registers); the stream accumulator
|
|
189
|
+
* threw on the first streamed token without them (P29a canary).
|
|
190
|
+
*/
|
|
187
191
|
export declare const contentSplitterPrimitives: () => ContentSplitterPrimitives;
|
|
188
192
|
/** A host with no shape catalog has no shapes to browse: the read says so, the picker shows it. */
|
|
189
193
|
export declare const fetchShapePage: (query: EntityListQuery, sort: EntityListSort) => Promise<EntityListPage<ShapeBrowseRow>>;
|
|
@@ -2,6 +2,7 @@ import { sanitizeInboundEnvelopeMetadata as sanitizeInboundEnvelopeMetadataPure
|
|
|
2
2
|
import { captureError } from "./diagnostics.js";
|
|
3
3
|
import { createElement } from "react";
|
|
4
4
|
import { hostFn, hostSlot } from "./ui-slots.js";
|
|
5
|
+
import * as splitterCore from "@ai-matrx/rich-content/display/markdown-classification/processors/utils/content-splitter-core";
|
|
5
6
|
const CONVERSATION_ANCHOR_TYPE = "conversation";
|
|
6
7
|
const KindInstanceRender = hostSlot(
|
|
7
8
|
"KindInstanceRender",
|
|
@@ -63,7 +64,10 @@ const contentIrKindValidator = hostFn("contentIrKindValidator", () => ({
|
|
|
63
64
|
invalidate: () => void 0
|
|
64
65
|
}));
|
|
65
66
|
const progressDataRenderBlock = hostFn("progressDataRenderBlock", () => null);
|
|
66
|
-
const contentSplitterPrimitives = hostFn(
|
|
67
|
+
const contentSplitterPrimitives = hostFn(
|
|
68
|
+
"contentSplitterPrimitives",
|
|
69
|
+
() => splitterCore
|
|
70
|
+
);
|
|
67
71
|
const fetchShapePage = hostFn("fetchShapePage", async () => {
|
|
68
72
|
throw new Error("This host has no shape catalog (registerChatUi fetchShapePage)");
|
|
69
73
|
});
|
package/dist/host/contract.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { CanvasJson } from "@ai-matrx/canvas";
|
|
|
24
24
|
import type { ChatCanvasTabKind } from "./canvas-tabs.js";
|
|
25
25
|
import type { ChatWindowOpeners } from "./window-openers.js";
|
|
26
26
|
import type { DefaultChatServerApi, DefaultChatServerTypes } from "./defaults/server-api.js";
|
|
27
|
+
import type { ChatMessageSource } from "./source.js";
|
|
27
28
|
/**
|
|
28
29
|
* The connection contract (R10). Authenticated, RLS applies. Typed with the
|
|
29
30
|
* package's own `ChatDatabase` (`./db-types`, generated: the schemas the
|
|
@@ -89,6 +90,11 @@ export interface ChatOrgPort {
|
|
|
89
90
|
* Never picks one on the person's behalf.
|
|
90
91
|
*/
|
|
91
92
|
require(reason: string, options?: ChatOrgRequireOptions): Promise<string>;
|
|
93
|
+
/**
|
|
94
|
+
* The person picked an organization in the package's own picker (the bare-host
|
|
95
|
+
* `WorkspaceGate`). Absent on a host that brings its own picker (matrx-frontend).
|
|
96
|
+
*/
|
|
97
|
+
choose?(org: ChatOrganization): void;
|
|
92
98
|
}
|
|
93
99
|
/**
|
|
94
100
|
* The host's server client and its types, REGISTERED by module augmentation —
|
|
@@ -718,15 +724,39 @@ export interface ChatCanvasPort {
|
|
|
718
724
|
useOpeners(): ChatCanvasOpeners;
|
|
719
725
|
useTab(tab: ChatCanvasTabRef): ChatCanvasTab;
|
|
720
726
|
}
|
|
727
|
+
/** How a host names itself on the conversations it starts. */
|
|
728
|
+
export interface ChatAppIdentity {
|
|
729
|
+
/** `chat.conversation.source_app` — a producer registered with the server. */
|
|
730
|
+
sourceApp: string;
|
|
731
|
+
/** `source_feature` for every conversation this app starts; absent keeps each screen's own. */
|
|
732
|
+
sourceFeature?: string;
|
|
733
|
+
}
|
|
721
734
|
export interface ChatHost {
|
|
722
|
-
/**
|
|
723
|
-
|
|
735
|
+
/**
|
|
736
|
+
* R10 connection contract. Authenticated, RLS applies. Required unless `source` is given: a
|
|
737
|
+
* host with no database gets the no-database stand-in (`./no-database`), which refuses and
|
|
738
|
+
* says so per feature.
|
|
739
|
+
*/
|
|
740
|
+
db?: ChatDb;
|
|
741
|
+
/**
|
|
742
|
+
* A host-owned message source (`./source`, HOST-OWNED-SOURCE-PLAN §2.2): conversations bound
|
|
743
|
+
* to it (`useHostConversation`) load, stream and send through the host, never a database.
|
|
744
|
+
* Both may be given; at least one is required.
|
|
745
|
+
*/
|
|
746
|
+
source?: ChatMessageSource;
|
|
724
747
|
/**
|
|
725
748
|
* Which client this is, for the platform errors system (`log_client_error`'s
|
|
726
749
|
* closed `p_source_app` list). Absent or off the list: diagnostics stay on the
|
|
727
750
|
* console and say so once.
|
|
728
751
|
*/
|
|
729
752
|
sourceApp?: ChatSourceApp;
|
|
753
|
+
/**
|
|
754
|
+
* What this app calls itself on the conversations it starts (`source_app`, and when given a
|
|
755
|
+
* `source_feature` that replaces the per-screen one). Both must be registered with the server
|
|
756
|
+
* (`source_attribution`). Absent: the neutral app `chat` and each screen's own feature — a host
|
|
757
|
+
* that is not matrx-frontend never labels its rows as the main app's.
|
|
758
|
+
*/
|
|
759
|
+
app?: ChatAppIdentity;
|
|
730
760
|
/** Default: from db.auth (getSession + onAuthStateChange); admin level from admin.admins. */
|
|
731
761
|
identity?: ChatIdentityPort;
|
|
732
762
|
/** Default: no active org; `require` refuses loudly (never auto-picks). */
|
|
@@ -765,8 +795,15 @@ export interface ChatHost {
|
|
|
765
795
|
export type ChatPortName = "identity" | "org" | "server" | "notify" | "diagnostics" | "prefs" | "navigation" | "windows" | "catalog" | "registry" | "chrome" | "feedback" | "routes" | "canvas";
|
|
766
796
|
/** Every port present. `overridden` names the ports the host supplied itself. */
|
|
767
797
|
export interface ResolvedChatHost {
|
|
798
|
+
/** The host's client, or the no-database stand-in when it gave only a `source`. */
|
|
768
799
|
db: ChatDb;
|
|
800
|
+
/** False when `db` is the stand-in. */
|
|
801
|
+
hasDatabase: boolean;
|
|
802
|
+
/** The host's message source, or null. */
|
|
803
|
+
source: ChatMessageSource | null;
|
|
769
804
|
sourceApp: ChatSourceApp | null;
|
|
805
|
+
/** The app's identity on the conversations it starts (`DEFAULT_CHAT_APP` when the host gave none). */
|
|
806
|
+
app: ChatAppIdentity;
|
|
770
807
|
identity: ChatIdentityPort;
|
|
771
808
|
org: ChatOrgPort;
|
|
772
809
|
server: ResolvedChatServerPort;
|
package/dist/host/db-types.d.ts
CHANGED
|
@@ -7156,6 +7156,13 @@ export type ChatDatabase = {
|
|
|
7156
7156
|
referencedRelation: "user_request_summary";
|
|
7157
7157
|
referencedColumns: ["id"];
|
|
7158
7158
|
},
|
|
7159
|
+
{
|
|
7160
|
+
foreignKeyName: "fk_cx_tool_call_parent";
|
|
7161
|
+
columns: ["parent_call_id"];
|
|
7162
|
+
isOneToOne: false;
|
|
7163
|
+
referencedRelation: "_tool_call_facts";
|
|
7164
|
+
referencedColumns: ["tool_call_id"];
|
|
7165
|
+
},
|
|
7159
7166
|
{
|
|
7160
7167
|
foreignKeyName: "fk_cx_tool_call_parent";
|
|
7161
7168
|
columns: ["parent_call_id"];
|
|
@@ -7559,6 +7566,48 @@ export type ChatDatabase = {
|
|
|
7559
7566
|
};
|
|
7560
7567
|
};
|
|
7561
7568
|
Views: {
|
|
7569
|
+
_tool_call_facts: {
|
|
7570
|
+
Row: {
|
|
7571
|
+
after_trim: number | null;
|
|
7572
|
+
agent_id: string | null;
|
|
7573
|
+
chars_refetched_same_data: number | null;
|
|
7574
|
+
conversation_id: string | null;
|
|
7575
|
+
created_at: string | null;
|
|
7576
|
+
gap_calls: number | null;
|
|
7577
|
+
gap_secs: number | null;
|
|
7578
|
+
is_repeat: number | null;
|
|
7579
|
+
new_data: number | null;
|
|
7580
|
+
output_chars: number | null;
|
|
7581
|
+
person_id: string | null;
|
|
7582
|
+
same_data: number | null;
|
|
7583
|
+
tool_call_id: string | null;
|
|
7584
|
+
tool_name: string | null;
|
|
7585
|
+
unknown_data: number | null;
|
|
7586
|
+
};
|
|
7587
|
+
Relationships: [
|
|
7588
|
+
{
|
|
7589
|
+
foreignKeyName: "cx_tool_call_conversation_id_fkey";
|
|
7590
|
+
columns: ["conversation_id"];
|
|
7591
|
+
isOneToOne: false;
|
|
7592
|
+
referencedRelation: "admin_conversation_summary";
|
|
7593
|
+
referencedColumns: ["id"];
|
|
7594
|
+
},
|
|
7595
|
+
{
|
|
7596
|
+
foreignKeyName: "cx_tool_call_conversation_id_fkey";
|
|
7597
|
+
columns: ["conversation_id"];
|
|
7598
|
+
isOneToOne: false;
|
|
7599
|
+
referencedRelation: "conversation";
|
|
7600
|
+
referencedColumns: ["id"];
|
|
7601
|
+
},
|
|
7602
|
+
{
|
|
7603
|
+
foreignKeyName: "cx_tool_call_conversation_id_fkey";
|
|
7604
|
+
columns: ["conversation_id"];
|
|
7605
|
+
isOneToOne: false;
|
|
7606
|
+
referencedRelation: "conversation_summary";
|
|
7607
|
+
referencedColumns: ["id"];
|
|
7608
|
+
}
|
|
7609
|
+
];
|
|
7610
|
+
};
|
|
7562
7611
|
admin_conversation_summary: {
|
|
7563
7612
|
Row: {
|
|
7564
7613
|
conversation_type: string | null;
|
|
@@ -30382,6 +30431,14 @@ export type ChatDatabase = {
|
|
|
30382
30431
|
Args: never;
|
|
30383
30432
|
Returns: Json;
|
|
30384
30433
|
};
|
|
30434
|
+
drill_def__tool_refetch: {
|
|
30435
|
+
Args: never;
|
|
30436
|
+
Returns: Json;
|
|
30437
|
+
};
|
|
30438
|
+
drill_def__user_acquisition: {
|
|
30439
|
+
Args: never;
|
|
30440
|
+
Returns: Json;
|
|
30441
|
+
};
|
|
30385
30442
|
drill_def__workflow_runs: {
|
|
30386
30443
|
Args: never;
|
|
30387
30444
|
Returns: Json;
|
|
@@ -51548,7 +51605,30 @@ export type ChatDatabase = {
|
|
|
51548
51605
|
};
|
|
51549
51606
|
};
|
|
51550
51607
|
Views: {
|
|
51551
|
-
|
|
51608
|
+
_acquisition_facts: {
|
|
51609
|
+
Row: {
|
|
51610
|
+
blocked: boolean | null;
|
|
51611
|
+
campaign: string | null;
|
|
51612
|
+
converted_at: string | null;
|
|
51613
|
+
cost: number | null;
|
|
51614
|
+
created_at: string | null;
|
|
51615
|
+
guest_id: string | null;
|
|
51616
|
+
identity_id: string | null;
|
|
51617
|
+
identity_state: string | null;
|
|
51618
|
+
landing_host: string | null;
|
|
51619
|
+
landing_path: string | null;
|
|
51620
|
+
person_id: string | null;
|
|
51621
|
+
referrer: string | null;
|
|
51622
|
+
referrer_host: string | null;
|
|
51623
|
+
referrer_state: string | null;
|
|
51624
|
+
requests: number | null;
|
|
51625
|
+
traffic_kind: string | null;
|
|
51626
|
+
utm_campaign: string | null;
|
|
51627
|
+
utm_medium: string | null;
|
|
51628
|
+
utm_source: string | null;
|
|
51629
|
+
};
|
|
51630
|
+
Relationships: [];
|
|
51631
|
+
};
|
|
51552
51632
|
};
|
|
51553
51633
|
Functions: {
|
|
51554
51634
|
_set_own_organization_choice: {
|
|
@@ -51558,6 +51638,20 @@ export type ChatDatabase = {
|
|
|
51558
51638
|
};
|
|
51559
51639
|
Returns: string;
|
|
51560
51640
|
};
|
|
51641
|
+
acquisition_host_is_local: {
|
|
51642
|
+
Args: {
|
|
51643
|
+
p_host: string;
|
|
51644
|
+
};
|
|
51645
|
+
Returns: boolean;
|
|
51646
|
+
};
|
|
51647
|
+
acquisition_traffic_kind: {
|
|
51648
|
+
Args: {
|
|
51649
|
+
p_landing_host: string;
|
|
51650
|
+
p_referrer: string;
|
|
51651
|
+
p_user_agent: string;
|
|
51652
|
+
};
|
|
51653
|
+
Returns: string;
|
|
51654
|
+
};
|
|
51561
51655
|
admin_account_facts: {
|
|
51562
51656
|
Args: never;
|
|
51563
51657
|
Returns: {
|
|
@@ -51633,6 +51727,10 @@ export type ChatDatabase = {
|
|
|
51633
51727
|
Args: never;
|
|
51634
51728
|
Returns: number;
|
|
51635
51729
|
};
|
|
51730
|
+
my_organization_choices: {
|
|
51731
|
+
Args: never;
|
|
51732
|
+
Returns: Json;
|
|
51733
|
+
};
|
|
51636
51734
|
my_organization_vault_access: {
|
|
51637
51735
|
Args: {
|
|
51638
51736
|
p_organization_id: string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
import type { ChatSearchParams } from "../contract.js";
|
|
2
|
+
/** Fired after the default port moves the address with the history API (no page load). */
|
|
3
|
+
export declare const CHAT_NAVIGATED_EVENT = "ai-matrx-chat:navigated";
|
|
2
4
|
export declare function useWindowPathname(): string;
|
|
3
5
|
export declare function useWindowSearchParams(): ChatSearchParams;
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useSyncExternalStore } from "react";
|
|
3
3
|
const hasWindow = () => typeof window !== "undefined";
|
|
4
|
+
const CHAT_NAVIGATED_EVENT = "ai-matrx-chat:navigated";
|
|
4
5
|
function subscribeToHistory(listener) {
|
|
5
6
|
if (!hasWindow()) return () => {
|
|
6
7
|
};
|
|
7
8
|
window.addEventListener("popstate", listener);
|
|
8
|
-
|
|
9
|
+
window.addEventListener(CHAT_NAVIGATED_EVENT, listener);
|
|
10
|
+
return () => {
|
|
11
|
+
window.removeEventListener("popstate", listener);
|
|
12
|
+
window.removeEventListener(CHAT_NAVIGATED_EVENT, listener);
|
|
13
|
+
};
|
|
9
14
|
}
|
|
10
15
|
function useWindowPathname() {
|
|
11
16
|
return useSyncExternalStore(
|
|
@@ -32,6 +37,7 @@ function useWindowSearchParams() {
|
|
|
32
37
|
return paramsFor(search);
|
|
33
38
|
}
|
|
34
39
|
export {
|
|
40
|
+
CHAT_NAVIGATED_EVENT,
|
|
35
41
|
useWindowPathname,
|
|
36
42
|
useWindowSearchParams
|
|
37
43
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Default navigation port:
|
|
3
|
-
*
|
|
4
|
-
* across back/forward
|
|
2
|
+
* Default navigation port: CLIENT-SIDE navigation through the history API (no page load, the
|
|
3
|
+
* mounted chat keeps its state), links as anchors that navigate the same way, the path and query
|
|
4
|
+
* read from `window.location` (kept current across back/forward and the port's own moves). An
|
|
5
|
+
* address on another origin is a real page load. matrx-frontend overrides with the package's Next
|
|
5
6
|
* binding (`next/navigation`).
|
|
6
7
|
*/
|
|
7
8
|
import type { ChatNavigationPort } from "../contract.js";
|
|
@@ -1,18 +1,49 @@
|
|
|
1
1
|
import { createElement } from "react";
|
|
2
|
-
import { useWindowPathname, useWindowSearchParams } from "./navigation-hooks.js";
|
|
3
|
-
|
|
2
|
+
import { CHAT_NAVIGATED_EVENT, useWindowPathname, useWindowSearchParams } from "./navigation-hooks.js";
|
|
3
|
+
const hasWindow = () => typeof window !== "undefined";
|
|
4
|
+
function sameOriginAddress(href) {
|
|
5
|
+
if (!hasWindow()) return null;
|
|
6
|
+
try {
|
|
7
|
+
const url = new URL(href, window.location.href);
|
|
8
|
+
return url.origin === window.location.origin ? url.pathname + url.search + url.hash : null;
|
|
9
|
+
} catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
function move(href, mode) {
|
|
14
|
+
if (!hasWindow()) return;
|
|
15
|
+
const address = sameOriginAddress(href);
|
|
16
|
+
if (address === null) {
|
|
17
|
+
if (mode === "push") window.location.assign(href);
|
|
18
|
+
else window.location.replace(href);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
if (mode === "push") window.history.pushState(null, "", address);
|
|
22
|
+
else window.history.replaceState(null, "", address);
|
|
23
|
+
window.dispatchEvent(new Event(CHAT_NAVIGATED_EVENT));
|
|
24
|
+
}
|
|
25
|
+
function PlainLink({ prefetch, replace, scroll, onClick, ...anchor }) {
|
|
4
26
|
void prefetch;
|
|
5
|
-
void replace;
|
|
6
27
|
void scroll;
|
|
7
|
-
return createElement("a",
|
|
28
|
+
return createElement("a", {
|
|
29
|
+
...anchor,
|
|
30
|
+
onClick: (event) => {
|
|
31
|
+
onClick?.(event);
|
|
32
|
+
const href = typeof anchor.href === "string" ? anchor.href : null;
|
|
33
|
+
if (event.defaultPrevented || !href || event.button !== 0 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey || anchor.target && anchor.target !== "_self" || sameOriginAddress(href) === null) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
event.preventDefault();
|
|
37
|
+
move(href, replace ? "replace" : "push");
|
|
38
|
+
}
|
|
39
|
+
});
|
|
8
40
|
}
|
|
9
|
-
const hasWindow = () => typeof window !== "undefined";
|
|
10
41
|
const windowRouter = {
|
|
11
42
|
push(href) {
|
|
12
|
-
|
|
43
|
+
move(href, "push");
|
|
13
44
|
},
|
|
14
45
|
replace(href) {
|
|
15
|
-
|
|
46
|
+
move(href, "replace");
|
|
16
47
|
},
|
|
17
48
|
back() {
|
|
18
49
|
if (hasWindow()) window.history.back();
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
2
|
+
* Org ports for a host that brings no organization port of its own.
|
|
3
|
+
*
|
|
4
|
+
* `createStoredOrg` (the default): the person picks in the package's own
|
|
5
|
+
* `WorkspaceGate` picker (`./workspace-gate.tsx`, memberships read over `db`),
|
|
6
|
+
* the choice is remembered on this device, and `require` resolves it. Nothing is
|
|
7
|
+
* ever picked on the person's behalf (hold-and-set); with no choice yet `require`
|
|
8
|
+
* refuses exactly like `createNoPickerOrg`, and the gate shows the picker.
|
|
9
|
+
* `createNoPickerOrg`: never an organization — for a host that must not write.
|
|
10
|
+
* A host with its own picker (matrx-frontend) overrides the port.
|
|
6
11
|
*/
|
|
7
12
|
import type { ChatDiagnosticsPort, ChatNotifyPort, ChatOrgPort } from "../contract.js";
|
|
8
13
|
export declare function createNoPickerOrg(notify: () => ChatNotifyPort, diagnostics: () => ChatDiagnosticsPort): ChatOrgPort;
|
|
14
|
+
/** Where the bare-host choice is remembered (this device only). */
|
|
15
|
+
export declare const CHAT_ACTIVE_ORG_STORAGE_KEY = "matrx-chat:active-organization";
|
|
16
|
+
export declare function createStoredOrg(notify: () => ChatNotifyPort, diagnostics: () => ChatDiagnosticsPort): ChatOrgPort;
|
|
@@ -18,6 +18,44 @@ function createNoPickerOrg(notify, diagnostics) {
|
|
|
18
18
|
}
|
|
19
19
|
};
|
|
20
20
|
}
|
|
21
|
+
const CHAT_ACTIVE_ORG_STORAGE_KEY = "matrx-chat:active-organization";
|
|
22
|
+
function readStored() {
|
|
23
|
+
try {
|
|
24
|
+
if (typeof window === "undefined" || !window.localStorage) return null;
|
|
25
|
+
const raw = window.localStorage.getItem(CHAT_ACTIVE_ORG_STORAGE_KEY);
|
|
26
|
+
if (!raw) return null;
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
return typeof parsed.id === "string" ? { id: parsed.id, name: parsed.name ?? null } : null;
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function createStoredOrg(notify, diagnostics) {
|
|
34
|
+
const refuse = createNoPickerOrg(notify, diagnostics);
|
|
35
|
+
let active = readStored();
|
|
36
|
+
const listeners = /* @__PURE__ */ new Set();
|
|
37
|
+
return {
|
|
38
|
+
active: () => active,
|
|
39
|
+
subscribe(listener) {
|
|
40
|
+
listeners.add(listener);
|
|
41
|
+
return () => listeners.delete(listener);
|
|
42
|
+
},
|
|
43
|
+
require(reason, options) {
|
|
44
|
+
if (active) return Promise.resolve(active.id);
|
|
45
|
+
return refuse.require(reason, options);
|
|
46
|
+
},
|
|
47
|
+
choose(org) {
|
|
48
|
+
active = { id: org.id, name: org.name };
|
|
49
|
+
try {
|
|
50
|
+
window.localStorage?.setItem(CHAT_ACTIVE_ORG_STORAGE_KEY, JSON.stringify(active));
|
|
51
|
+
} catch {
|
|
52
|
+
}
|
|
53
|
+
for (const listener of [...listeners]) listener();
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
}
|
|
21
57
|
export {
|
|
22
|
-
|
|
58
|
+
CHAT_ACTIVE_ORG_STORAGE_KEY,
|
|
59
|
+
createNoPickerOrg,
|
|
60
|
+
createStoredOrg
|
|
23
61
|
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The bare-host `WorkspaceGate`: when a surface is blocked on "no organization chosen",
|
|
3
|
+
* the same area lists the organizations the person belongs to (read over `host.db`) and
|
|
4
|
+
* picking one makes it active (`host.org.choose`). Nothing is picked for the person.
|
|
5
|
+
* A host with its own picker (matrx-frontend) registers its own gate.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReactNode } from "react";
|
|
8
|
+
export interface DefaultWorkspaceGateProps {
|
|
9
|
+
blocked: boolean;
|
|
10
|
+
sentence: string;
|
|
11
|
+
description?: string;
|
|
12
|
+
children?: ReactNode;
|
|
13
|
+
compact?: boolean;
|
|
14
|
+
className?: string;
|
|
15
|
+
}
|
|
16
|
+
export declare function DefaultWorkspaceGate({ blocked, sentence, description, children, className }: DefaultWorkspaceGateProps): import("react").JSX.Element;
|