@ai-matrx/chat 0.4.14 → 0.4.15

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @ai-matrx/chat
2
2
 
3
+ ## 0.4.15
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/chat/v0.4.14..npm/chat/v0.4.15 -- apps/shared/chat`).
7
+ No source changes intended and no consumer action required.
8
+
3
9
  ## 0.4.14 — token-only hosts, on-device tools, and a bundle budget (W0(b), W0(c), W0(e))
4
10
 
5
11
  - **Token-only database clients** (supabase-js `accessToken` option — matrx-local's custodian
@@ -1,5 +1,5 @@
1
1
  import { Eye } from "lucide-react";
2
- export type AgentPageMode = "view" | "edit" | "run" | "shortcuts" | "apps" | "surfaces" | "hindsight" | "versions" | "widgets";
2
+ export type AgentPageMode = "view" | "edit" | "run" | "shortcuts" | "apps" | "surfaces" | "hindsight" | "runs" | "versions" | "widgets";
3
3
  export type ModeOption = AgentPageMode | "new";
4
4
  export declare const MODES: {
5
5
  id: ModeOption;
@@ -3,6 +3,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState, useTransition } from "react";
4
4
  import { useRouter, usePathname, Link } from "../../../host/navigation.js";
5
5
  import {
6
+ Activity,
6
7
  AppWindow,
7
8
  Eye,
8
9
  History,
@@ -40,6 +41,7 @@ const MODES = [
40
41
  { id: "apps", label: "Apps", icon: AppWindow },
41
42
  { id: "surfaces", label: "Surfaces", icon: Layers },
42
43
  { id: "hindsight", label: "Review", icon: Telescope },
44
+ { id: "runs", label: "Runs", icon: Activity },
43
45
  { id: "versions", label: "Versions", icon: History },
44
46
  { id: "widgets", label: "Widgets", icon: LayoutGrid },
45
47
  { id: "new", label: "New", icon: Plus }
@@ -54,6 +56,7 @@ function getAgentModeHref(mode, agentId, basePath) {
54
56
  apps: `${basePath}/${agentId}/apps`,
55
57
  surfaces: `${basePath}/${agentId}/surfaces`,
56
58
  hindsight: `${basePath}/${agentId}/hindsight`,
59
+ runs: `${basePath}/${agentId}/runs`,
57
60
  versions: `${basePath}/${agentId}/latest`,
58
61
  widgets: `${basePath}/${agentId}/widgets`
59
62
  };
@@ -67,6 +70,7 @@ function deriveAgentMode(pathname, agentId, basePath) {
67
70
  if (pathname.startsWith(`${base}/apps`)) return "apps";
68
71
  if (pathname.startsWith(`${base}/surfaces`)) return "surfaces";
69
72
  if (pathname.startsWith(`${base}/hindsight`)) return "hindsight";
73
+ if (pathname.startsWith(`${base}/runs`)) return "runs";
70
74
  if (pathname.startsWith(`${base}/widgets`)) return "widgets";
71
75
  const versionPattern = new RegExp(
72
76
  `^${basePath.replace(/\//g, "\\/")}\\/[^/]+\\/v\\/\\d+$`
@@ -1,5 +1,5 @@
1
1
  import { createSlice } from "@reduxjs/toolkit";
2
- import isEqual from "lodash/isEqual";
2
+ import { deepEqual as isEqual } from "../../../../utils/deep-equal.js";
3
3
  import { destroyInstance } from "../conversations/conversations.slice.js";
4
4
  import { createInstanceFull } from "../create-instance-full.js";
5
5
  import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
@@ -1,3 +1,4 @@
1
+ import { deepEqual } from "../../utils/deep-equal.js";
1
2
  function computeSettingsOverrides(agentDefaults, userSettings) {
2
3
  const defaults = agentDefaults ?? {};
3
4
  const user = userSettings;
@@ -19,27 +20,6 @@ function computeSettingsOverrides(agentDefaults, userSettings) {
19
20
  }
20
21
  return hasOverrides ? overrides : null;
21
22
  }
22
- function deepEqual(a, b) {
23
- if (a === b) return true;
24
- if (a === null || b === null) return false;
25
- if (typeof a !== typeof b) return false;
26
- if (Array.isArray(a) && Array.isArray(b)) {
27
- if (a.length !== b.length) return false;
28
- return a.every((val, i) => deepEqual(val, b[i]));
29
- }
30
- if (typeof a === "object" && typeof b === "object") {
31
- const keysA = Object.keys(a);
32
- const keysB = Object.keys(b);
33
- if (keysA.length !== keysB.length) return false;
34
- return keysA.every(
35
- (key) => deepEqual(
36
- a[key],
37
- b[key]
38
- )
39
- );
40
- }
41
- return false;
42
- }
43
23
  export {
44
24
  computeSettingsOverrides
45
25
  };
@@ -16251,6 +16251,10 @@ export type ChatDatabase = {
16251
16251
  token: string;
16252
16252
  }[];
16253
16253
  };
16254
+ access_shadow_status: {
16255
+ Args: never;
16256
+ Returns: Json;
16257
+ };
16254
16258
  accessible_child_parents: {
16255
16259
  Args: {
16256
16260
  p_child_type: string;
@@ -17034,12 +17038,25 @@ export type ChatDatabase = {
17034
17038
  Args: never;
17035
17039
  Returns: boolean;
17036
17040
  };
17041
+ kernel_set_form_on: {
17042
+ Args: {
17043
+ p_person: string;
17044
+ };
17045
+ Returns: boolean;
17046
+ };
17037
17047
  kernel_shadow_on: {
17038
17048
  Args: {
17039
17049
  p_person: string;
17040
17050
  };
17041
17051
  Returns: boolean;
17042
17052
  };
17053
+ kernel_shadow_sweep: {
17054
+ Args: {
17055
+ p_people?: number;
17056
+ p_tables?: number;
17057
+ };
17058
+ Returns: Json;
17059
+ };
17043
17060
  lane_of: {
17044
17061
  Args: {
17045
17062
  p_resource_id: string;
@@ -19866,6 +19883,21 @@ export type ChatDatabase = {
19866
19883
  version_live: boolean;
19867
19884
  }[];
19868
19885
  };
19886
+ run_history: {
19887
+ Args: {
19888
+ p_agent_id?: string;
19889
+ p_desc?: boolean;
19890
+ p_limit?: number;
19891
+ p_mandate_key?: string;
19892
+ p_offset?: number;
19893
+ p_org_id?: string;
19894
+ p_sort?: string;
19895
+ p_status?: string;
19896
+ p_user_id?: string;
19897
+ p_view?: string;
19898
+ };
19899
+ Returns: Json;
19900
+ };
19869
19901
  sanitize_app_segment: {
19870
19902
  Args: {
19871
19903
  p_seg: string;
@@ -28302,6 +28334,26 @@ export type ChatDatabase = {
28302
28334
  };
28303
28335
  Returns: Json;
28304
28336
  };
28337
+ _drill_fine_agg_sql: {
28338
+ Args: {
28339
+ p_cnt: string;
28340
+ p_col: string;
28341
+ p_filter?: string;
28342
+ p_measure: Json;
28343
+ p_once: string;
28344
+ };
28345
+ Returns: string;
28346
+ };
28347
+ _drill_fine_ratio_sql: {
28348
+ Args: {
28349
+ p_cnt: string;
28350
+ p_filter?: string;
28351
+ p_measure: Json;
28352
+ p_once: string;
28353
+ p_prefix: string;
28354
+ };
28355
+ Returns: string;
28356
+ };
28305
28357
  _drill_fk: {
28306
28358
  Args: {
28307
28359
  p_column: string;
@@ -30411,6 +30463,10 @@ export type ChatDatabase = {
30411
30463
  Args: never;
30412
30464
  Returns: Json;
30413
30465
  };
30466
+ drill_def__account_roster: {
30467
+ Args: never;
30468
+ Returns: Json;
30469
+ };
30414
30470
  drill_def__agents_by_model: {
30415
30471
  Args: never;
30416
30472
  Returns: Json;
@@ -30427,10 +30483,46 @@ export type ChatDatabase = {
30427
30483
  Args: never;
30428
30484
  Returns: Json;
30429
30485
  };
30486
+ drill_def__app_log: {
30487
+ Args: never;
30488
+ Returns: Json;
30489
+ };
30490
+ drill_def__crm_deals: {
30491
+ Args: never;
30492
+ Returns: Json;
30493
+ };
30494
+ drill_def__cx_requests: {
30495
+ Args: never;
30496
+ Returns: Json;
30497
+ };
30498
+ drill_def__hr_timesheets: {
30499
+ Args: never;
30500
+ Returns: Json;
30501
+ };
30430
30502
  drill_def__kg_cost: {
30431
30503
  Args: never;
30432
30504
  Returns: Json;
30433
30505
  };
30506
+ drill_def__ops_issue_events: {
30507
+ Args: never;
30508
+ Returns: Json;
30509
+ };
30510
+ drill_def__rs_analyses: {
30511
+ Args: never;
30512
+ Returns: Json;
30513
+ };
30514
+ drill_def__rs_syntheses: {
30515
+ Args: never;
30516
+ Returns: Json;
30517
+ };
30518
+ drill_def__system_errors: {
30519
+ Args: never;
30520
+ Returns: Json;
30521
+ };
30522
+ drill_def__tool_calls: {
30523
+ Args: never;
30524
+ Returns: Json;
30525
+ };
30434
30526
  drill_def__tool_refetch: {
30435
30527
  Args: never;
30436
30528
  Returns: Json;
@@ -30443,6 +30535,10 @@ export type ChatDatabase = {
30443
30535
  Args: never;
30444
30536
  Returns: Json;
30445
30537
  };
30538
+ drill_def__write_failures: {
30539
+ Args: never;
30540
+ Returns: Json;
30541
+ };
30446
30542
  drill_definition_problems: {
30447
30543
  Args: {
30448
30544
  p_def: Json;
@@ -51605,6 +51701,22 @@ export type ChatDatabase = {
51605
51701
  };
51606
51702
  };
51607
51703
  Views: {
51704
+ _account_facts: {
51705
+ Row: {
51706
+ blocked: boolean | null;
51707
+ campaign: string | null;
51708
+ cost: number | null;
51709
+ created_at: string | null;
51710
+ identity_state: string | null;
51711
+ person_id: string | null;
51712
+ plan_key: string | null;
51713
+ plan_name: string | null;
51714
+ referrer_host: string | null;
51715
+ requests: number | null;
51716
+ traffic_kind: string | null;
51717
+ };
51718
+ Relationships: [];
51719
+ };
51608
51720
  _acquisition_facts: {
51609
51721
  Row: {
51610
51722
  blocked: boolean | null;
@@ -18,7 +18,8 @@ function slotComponent(name, Fallback) {
18
18
  const Wrapper = (props) => {
19
19
  const Impl = slots[name];
20
20
  if (!Impl) {
21
- reportUnregistered(name, Fallback ? "a plain stand-in is drawn" : "it renders nothing here");
21
+ const absent = !Fallback || Fallback.optionalAbsent;
22
+ reportUnregistered(name, absent ? "it renders nothing here" : "a plain stand-in is drawn");
22
23
  return Fallback ? createElement(Fallback, props) : null;
23
24
  }
24
25
  return createElement(Impl, props);
@@ -35,6 +36,12 @@ function unregisteredWidget(name) {
35
36
  UnregisteredWidget.displayName = `UnregisteredWidget(${name})`;
36
37
  return UnregisteredWidget;
37
38
  }
39
+ function optionalWidget(name) {
40
+ const AbsentOptionalWidget = () => null;
41
+ AbsentOptionalWidget.displayName = `AbsentOptionalWidget(${name})`;
42
+ AbsentOptionalWidget.optionalAbsent = true;
43
+ return AbsentOptionalWidget;
44
+ }
38
45
  function hostSlot(name, Fallback) {
39
46
  return slotComponent(name, Fallback);
40
47
  }
@@ -160,7 +167,7 @@ function slotFn(name, declared) {
160
167
  const CopyButtons = slotComponent("CopyButtons");
161
168
  const InfoHint = slotComponent("InfoHint");
162
169
  const AnswerValueView = slotComponent("AnswerValueView");
163
- const ErrorAlchemyMenu = slotComponent("ErrorAlchemyMenu", unregisteredWidget("ErrorAlchemyMenu"));
170
+ const ErrorAlchemyMenu = slotComponent("ErrorAlchemyMenu", optionalWidget("ErrorAlchemyMenu"));
164
171
  const ErrorNotice = slotComponent(
165
172
  "ErrorNotice",
166
173
  ({ title, message, error, actions, children, className }) => createElement(
@@ -187,16 +194,16 @@ const NonEditableContextMenu = slotComponent("NonEditableContextMenu", contentWi
187
194
  const TableChooser = slotComponent("TableChooser");
188
195
  const FileResourceChip = slotComponent("FileResourceChip");
189
196
  const ConnectorMark = slotComponent("ConnectorMark");
190
- const MessageFilesStrip = slotComponent("MessageFilesStrip", unregisteredWidget("MessageFilesStrip"));
191
- const RulebookNudge = slotComponent("RulebookNudge", unregisteredWidget("RulebookNudge"));
192
- const NegativeVerdictFollowUp = slotComponent("NegativeVerdictFollowUp", unregisteredWidget("NegativeVerdictFollowUp"));
193
- const SpeakerButton = slotComponent("SpeakerButton", unregisteredWidget("SpeakerButton"));
194
- const GmailReviewCard = slotComponent("GmailReviewCard", unregisteredWidget("GmailReviewCard"));
195
- const ShareButton = slotComponent("ShareButton", unregisteredWidget("ShareButton"));
196
- const ShareModal = slotComponent("ShareModal", unregisteredWidget("ShareModal"));
197
- const ReviewAnswersLink = slotComponent("ReviewAnswersLink", unregisteredWidget("ReviewAnswersLink"));
198
- const RecordChangeApprovalCard = slotComponent("RecordChangeApprovalCard", unregisteredWidget("RecordChangeApprovalCard"));
199
- const AttachedResourcesSection = slotComponent("AttachedResourcesSection", unregisteredWidget("AttachedResourcesSection"));
197
+ const MessageFilesStrip = slotComponent("MessageFilesStrip", optionalWidget("MessageFilesStrip"));
198
+ const RulebookNudge = slotComponent("RulebookNudge", optionalWidget("RulebookNudge"));
199
+ const NegativeVerdictFollowUp = slotComponent("NegativeVerdictFollowUp", optionalWidget("NegativeVerdictFollowUp"));
200
+ const SpeakerButton = slotComponent("SpeakerButton", optionalWidget("SpeakerButton"));
201
+ const GmailReviewCard = slotComponent("GmailReviewCard", optionalWidget("GmailReviewCard"));
202
+ const ShareButton = slotComponent("ShareButton", optionalWidget("ShareButton"));
203
+ const ShareModal = slotComponent("ShareModal", optionalWidget("ShareModal"));
204
+ const ReviewAnswersLink = slotComponent("ReviewAnswersLink", optionalWidget("ReviewAnswersLink"));
205
+ const RecordChangeApprovalCard = slotComponent("RecordChangeApprovalCard", optionalWidget("RecordChangeApprovalCard"));
206
+ const AttachedResourcesSection = slotComponent("AttachedResourcesSection", optionalWidget("AttachedResourcesSection"));
200
207
  const ConnectorPromptHost = slotComponent("ConnectorPromptHost");
201
208
  const WebpageSnapshotView = slotComponent("WebpageSnapshotView", DefaultWebpageSnapshotView);
202
209
  function hostFn(name, fallback) {
@@ -230,16 +237,16 @@ const traceWarRoomRenderPath = slotFn("traceWarRoomRenderPath", () => void 0);
230
237
  const isWarRoomThreadAgentSurface = slotFn("isWarRoomThreadAgentSurface", () => false);
231
238
  const useOpenCloudBrowserCanvas = slotFn("useOpenCloudBrowserCanvas", () => () => void 0);
232
239
  const cloudBrowserCanvasSourceId = slotFn("cloudBrowserCanvasSourceId", (conversationId) => `cloud-browser:${conversationId}`);
233
- const SystemInstructionModal = slotComponent("SystemInstructionModal", unregisteredWidget("SystemInstructionModal"));
240
+ const SystemInstructionModal = slotComponent("SystemInstructionModal", optionalWidget("SystemInstructionModal"));
234
241
  const WindowPanel = slotComponent("WindowPanel", DefaultWindowPanel);
235
242
  const FullScreenOverlay = slotComponent("FullScreenOverlay", DefaultFullScreenOverlay);
236
- const ResourcePickerWindow = slotComponent("ResourcePickerWindow", unregisteredWidget("ResourcePickerWindow"));
237
- const ResourcePickerMenu = slotComponent("ResourcePickerMenu", unregisteredWidget("ResourcePickerMenu"));
238
- const FilesResourcePicker = slotComponent("FilesResourcePicker", unregisteredWidget("FilesResourcePicker"));
239
- const NotePickerPopover = slotComponent("NotePickerPopover", unregisteredWidget("NotePickerPopover"));
243
+ const ResourcePickerWindow = slotComponent("ResourcePickerWindow", optionalWidget("ResourcePickerWindow"));
244
+ const ResourcePickerMenu = slotComponent("ResourcePickerMenu", optionalWidget("ResourcePickerMenu"));
245
+ const FilesResourcePicker = slotComponent("FilesResourcePicker", optionalWidget("FilesResourcePicker"));
246
+ const NotePickerPopover = slotComponent("NotePickerPopover", optionalWidget("NotePickerPopover"));
240
247
  const SmartInputMessageTemplatePicker = slotComponent(
241
248
  "SmartInputMessageTemplatePicker",
242
- unregisteredWidget("SmartInputMessageTemplatePicker")
249
+ optionalWidget("SmartInputMessageTemplatePicker")
243
250
  );
244
251
  const flattenResourcePickerItems = slotFn("flattenResourcePickerItems", defaultResourcePickerItems);
245
252
  const useRunControlCounts = slotFn("useRunControlCounts", () => ({}));
@@ -253,8 +260,8 @@ const emitFullScreenEditorSave = slotFn(
253
260
  () => Promise.reject(new Error("This host has no full-screen editor save target"))
254
261
  );
255
262
  const FileRagBadge = slotComponent("FileRagBadge");
256
- const MediaAttachmentThumbnail = slotComponent("MediaAttachmentThumbnail", unregisteredWidget("MediaAttachmentThumbnail"));
257
- const UnifiedImageBlockRenderer = slotComponent("UnifiedImageBlockRenderer", unregisteredWidget("UnifiedImageBlockRenderer"));
263
+ const MediaAttachmentThumbnail = slotComponent("MediaAttachmentThumbnail", optionalWidget("MediaAttachmentThumbnail"));
264
+ const UnifiedImageBlockRenderer = slotComponent("UnifiedImageBlockRenderer", optionalWidget("UnifiedImageBlockRenderer"));
258
265
  const MicrophoneIconButton = slotComponent("MicrophoneIconButton");
259
266
  const TranscriptionLoader = slotComponent("TranscriptionLoader");
260
267
  const MicDeviceMenu = slotComponent("MicDeviceMenu");
@@ -1961,6 +1961,21 @@ declare const definitionTable: (supabase: Client) => import("@supabase/supabase-
1961
1961
  version_live: boolean;
1962
1962
  }[];
1963
1963
  };
1964
+ run_history: {
1965
+ Args: {
1966
+ p_agent_id?: string;
1967
+ p_desc?: boolean;
1968
+ p_limit?: number;
1969
+ p_mandate_key?: string;
1970
+ p_offset?: number;
1971
+ p_org_id?: string;
1972
+ p_sort?: string;
1973
+ p_status?: string;
1974
+ p_user_id?: string;
1975
+ p_view?: string;
1976
+ };
1977
+ Returns: Json;
1978
+ };
1964
1979
  sanitize_app_segment: {
1965
1980
  Args: {
1966
1981
  p_seg: string;
@@ -4099,6 +4114,21 @@ declare const provisionTable: (supabase: Client) => import("@supabase/supabase-j
4099
4114
  version_live: boolean;
4100
4115
  }[];
4101
4116
  };
4117
+ run_history: {
4118
+ Args: {
4119
+ p_agent_id?: string;
4120
+ p_desc?: boolean;
4121
+ p_limit?: number;
4122
+ p_mandate_key?: string;
4123
+ p_offset?: number;
4124
+ p_org_id?: string;
4125
+ p_sort?: string;
4126
+ p_status?: string;
4127
+ p_user_id?: string;
4128
+ p_view?: string;
4129
+ };
4130
+ Returns: Json;
4131
+ };
4102
4132
  sanitize_app_segment: {
4103
4133
  Args: {
4104
4134
  p_seg: string;
@@ -6132,6 +6162,21 @@ declare const bindingTable: (supabase: Client) => import("@supabase/supabase-js"
6132
6162
  version_live: boolean;
6133
6163
  }[];
6134
6164
  };
6165
+ run_history: {
6166
+ Args: {
6167
+ p_agent_id?: string;
6168
+ p_desc?: boolean;
6169
+ p_limit?: number;
6170
+ p_mandate_key?: string;
6171
+ p_offset?: number;
6172
+ p_org_id?: string;
6173
+ p_sort?: string;
6174
+ p_status?: string;
6175
+ p_user_id?: string;
6176
+ p_view?: string;
6177
+ };
6178
+ Returns: Json;
6179
+ };
6135
6180
  sanitize_app_segment: {
6136
6181
  Args: {
6137
6182
  p_seg: string;
@@ -8213,6 +8258,21 @@ declare const treatmentTable: (supabase: Client) => import("@supabase/supabase-j
8213
8258
  version_live: boolean;
8214
8259
  }[];
8215
8260
  };
8261
+ run_history: {
8262
+ Args: {
8263
+ p_agent_id?: string;
8264
+ p_desc?: boolean;
8265
+ p_limit?: number;
8266
+ p_mandate_key?: string;
8267
+ p_offset?: number;
8268
+ p_org_id?: string;
8269
+ p_sort?: string;
8270
+ p_status?: string;
8271
+ p_user_id?: string;
8272
+ p_view?: string;
8273
+ };
8274
+ Returns: Json;
8275
+ };
8216
8276
  sanitize_app_segment: {
8217
8277
  Args: {
8218
8278
  p_seg: string;
@@ -6191,6 +6191,21 @@ declare const mandateContextMenuView: (supabase: Client) => import("@supabase/su
6191
6191
  version_live: boolean;
6192
6192
  }[];
6193
6193
  };
6194
+ run_history: {
6195
+ Args: {
6196
+ p_agent_id?: string;
6197
+ p_desc?: boolean;
6198
+ p_limit?: number;
6199
+ p_mandate_key?: string;
6200
+ p_offset?: number;
6201
+ p_org_id?: string;
6202
+ p_sort?: string;
6203
+ p_status?: string;
6204
+ p_user_id?: string;
6205
+ p_view?: string;
6206
+ };
6207
+ Returns: import("../../host/db-types.js").Json;
6208
+ };
6194
6209
  sanitize_app_segment: {
6195
6210
  Args: {
6196
6211
  p_seg: string;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Structural equality for plain data (JSON-shaped values, Dates, Maps, Sets). A local util so no
3
+ * module needs a bare `lodash/isEqual` import, which Node ESM cannot resolve.
4
+ */
5
+ export declare function deepEqual(a: unknown, b: unknown): boolean;
@@ -0,0 +1,24 @@
1
+ function deepEqual(a, b) {
2
+ if (Object.is(a, b)) return true;
3
+ if (typeof a !== "object" || typeof b !== "object" || a === null || b === null) return false;
4
+ if (Array.isArray(a) !== Array.isArray(b)) return false;
5
+ if (a instanceof Date || b instanceof Date) return a instanceof Date && b instanceof Date && a.getTime() === b.getTime();
6
+ if (a instanceof Map || b instanceof Map) {
7
+ if (!(a instanceof Map && b instanceof Map) || a.size !== b.size) return false;
8
+ for (const [k, v] of a) if (!b.has(k) || !deepEqual(v, b.get(k))) return false;
9
+ return true;
10
+ }
11
+ if (a instanceof Set || b instanceof Set) {
12
+ if (!(a instanceof Set && b instanceof Set) || a.size !== b.size) return false;
13
+ for (const v of a) if (!b.has(v)) return false;
14
+ return true;
15
+ }
16
+ const ra = a;
17
+ const rb = b;
18
+ const keysA = Object.keys(ra);
19
+ if (keysA.length !== Object.keys(rb).length) return false;
20
+ return keysA.every((k) => Object.prototype.hasOwnProperty.call(rb, k) && deepEqual(ra[k], rb[k]));
21
+ }
22
+ export {
23
+ deepEqual
24
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-matrx/chat",
3
- "version": "0.4.14",
3
+ "version": "0.4.15",
4
4
  "description": "THE one AI Matrx person-to-agent chat system: the full chat (running agents, conversations, tool calls, streaming, context, surfaces, voice) as per-module subpaths @ai-matrx/chat/<domain>/<module> over a host contract (/host, /host/react) whose only required value is a db; plus the kernel compatibility entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) until P28.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -233,19 +233,19 @@
233
233
  "@ai-matrx/canvas": "latest",
234
234
  "@ai-matrx/content-ir": "latest",
235
235
  "@ai-matrx/data": "latest",
236
- "@ai-matrx/content-ir-react": "latest",
237
236
  "@ai-matrx/design-system": "latest",
238
237
  "@ai-matrx/diff": "latest",
239
238
  "@ai-matrx/icons": "latest",
240
239
  "@ai-matrx/kit": "latest",
241
240
  "@ai-matrx/media": "latest",
241
+ "@ai-matrx/print": "latest",
242
242
  "@ai-matrx/realtime": "latest",
243
- "@ai-matrx/records": "latest",
244
243
  "@ai-matrx/records-ui": "latest",
245
- "@ai-matrx/rich-editor": "latest",
246
244
  "@ai-matrx/rich-content": "latest",
245
+ "@ai-matrx/rich-editor": "latest",
247
246
  "@ai-matrx/tap-target": "latest",
248
- "@ai-matrx/print": "latest"
247
+ "@ai-matrx/records": "latest",
248
+ "@ai-matrx/content-ir-react": "latest"
249
249
  },
250
250
  "devDependencies": {
251
251
  "@arethetypeswrong/cli": "^0.18.5",