@ai-matrx/chat 0.7.22 → 0.7.23
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 +21 -0
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.d.ts +1 -1
- package/dist/agents/redux/execution-system/thunks/continue-agent-json.js +3 -1
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.d.ts +19 -0
- package/dist/agents/redux/execution-system/thunks/run-headless-agent-json.js +99 -2
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +11 -4
- package/dist/ui/markdown-stream/waiting-for-content.d.ts +15 -0
- package/dist/ui/markdown-stream/waiting-for-content.js +10 -0
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @ai-matrx/chat
|
|
2
2
|
|
|
3
|
+
## 0.7.23
|
|
4
|
+
### Unreleased
|
|
5
|
+
|
|
6
|
+
### A run parked on the person waits for them (lane F15)
|
|
7
|
+
|
|
8
|
+
- **`runHeadlessAgentJson` / `adoptHeadlessAgentJson` / `continueAgentJson`: waiting on the person is a
|
|
9
|
+
waiting state, never a failure.** A turn that ends parked on a question (`ask_person`,
|
|
10
|
+
`suspended_awaiting_client`) no longer settles from the parked call (the Applet builder said "The
|
|
11
|
+
builder answered without an app" over a question it never showed). The wait fires the new
|
|
12
|
+
`onAwaitingPerson`, pauses `timeoutMs`, re-reads the conversation (`rereadAndFollow`) when the ask
|
|
13
|
+
closes anywhere, and resolves from the resumed turn's answer; `personWaitMs` (default 6h) bounds it.
|
|
14
|
+
A parked run that stops waiting harvests nothing (`awaitingPerson: true`). Consumer action: a surface
|
|
15
|
+
that runs an agent which may ask passes `onAwaitingPerson` to say it is waiting.
|
|
16
|
+
- **A dropped connection is not a failed run.** When the stream dies on a connection loss
|
|
17
|
+
(`transport_lost` / `heartbeat_timeout`) the server finishes the turn and `reconnectServerOperation`
|
|
18
|
+
re-reads it; the headless wait now waits for that (5 min ceiling) and resolves from the answer it
|
|
19
|
+
brings, instead of failing "before returning a result" while the build finished on the server. A
|
|
20
|
+
reconnect that brings nothing ends with the stream's own reason. Consumer action: none.
|
|
21
|
+
- **A settled turn that ended on a tool call shows the call, not "Processing…"** (`isWaitingForFirstContent`):
|
|
22
|
+
the parked ask's card now draws in place of a shimmer that never ended. Consumer action: none.
|
|
23
|
+
|
|
3
24
|
## 0.7.22
|
|
4
25
|
|
|
5
26
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
@@ -22,7 +22,7 @@ import type { RequestInitiation } from "../../../types/instance.types.js";
|
|
|
22
22
|
import type { Resource } from "../../../resources/types.js";
|
|
23
23
|
import { type HostTurnInput } from "./execute-instance.thunk.js";
|
|
24
24
|
import { type AdoptedAgentJsonOptions, type HeadlessAgentJsonResult } from "./run-headless-agent-json.js";
|
|
25
|
-
export interface ContinueAgentJsonOptions extends Pick<AdoptedAgentJsonOptions, "surfaceKey" | "timeoutMs" | "pollIntervalMs" | "settleMs" | "expect" | "onResult" | "signal" | "failureMessages"> {
|
|
25
|
+
export interface ContinueAgentJsonOptions extends Pick<AdoptedAgentJsonOptions, "surfaceKey" | "timeoutMs" | "pollIntervalMs" | "settleMs" | "expect" | "onResult" | "signal" | "failureMessages" | "onAwaitingPerson" | "personWaitMs"> {
|
|
26
26
|
conversationId: string;
|
|
27
27
|
/** What the person typed for this turn. Exclusive with `hostTurn`. */
|
|
28
28
|
userInput?: string;
|
|
@@ -54,7 +54,9 @@ async function continueAgentJson(dispatch, getState, opts) {
|
|
|
54
54
|
...opts.expect ? { expect: opts.expect } : {},
|
|
55
55
|
...opts.onResult ? { onResult: opts.onResult } : {},
|
|
56
56
|
...opts.signal ? { signal: opts.signal } : {},
|
|
57
|
-
...opts.failureMessages ? { failureMessages: opts.failureMessages } : {}
|
|
57
|
+
...opts.failureMessages ? { failureMessages: opts.failureMessages } : {},
|
|
58
|
+
...opts.onAwaitingPerson ? { onAwaitingPerson: opts.onAwaitingPerson } : {},
|
|
59
|
+
...opts.personWaitMs !== void 0 ? { personWaitMs: opts.personWaitMs } : {}
|
|
58
60
|
});
|
|
59
61
|
} catch (err) {
|
|
60
62
|
const message = err instanceof Error ? err.message : String(err);
|
|
@@ -168,6 +168,19 @@ export interface HeadlessAgentJsonOptions {
|
|
|
168
168
|
* discards. Pair it with `onResult` so an unmounting surface still persists.
|
|
169
169
|
*/
|
|
170
170
|
signal?: AbortSignal;
|
|
171
|
+
/**
|
|
172
|
+
* THE RUN IS WAITING ON THE PERSON, NOT FAILED. The turn ended parked on a question
|
|
173
|
+
* (`ask_person`, or a server park on a person): its answer is the turn that resumes once
|
|
174
|
+
* they answer. The wait pauses `timeoutMs`, fires this once so the surface can say so and
|
|
175
|
+
* show the question, re-reads the conversation when the ask closes (answered here, in
|
|
176
|
+
* another tab or by text), and resolves from the resumed turn. Bounded by `personWaitMs`.
|
|
177
|
+
*/
|
|
178
|
+
onAwaitingPerson?: (info: {
|
|
179
|
+
requestId: string;
|
|
180
|
+
conversationId: string;
|
|
181
|
+
}) => void;
|
|
182
|
+
/** Ceiling on waiting for the person once a run parks on them. Default 6h; `signal` stops it sooner. */
|
|
183
|
+
personWaitMs?: number;
|
|
171
184
|
/** Fires with the conversation id BEFORE the stream runs (live UI handle). */
|
|
172
185
|
onConversationCreated?: (conversationId: string) => void;
|
|
173
186
|
/**
|
|
@@ -271,6 +284,8 @@ export interface HeadlessAgentJsonResult {
|
|
|
271
284
|
* from a failure that carries its own reason.
|
|
272
285
|
*/
|
|
273
286
|
noResult?: boolean;
|
|
287
|
+
/** `true` when the run ended parked on the person and stopped waiting before they answered. */
|
|
288
|
+
awaitingPerson?: boolean;
|
|
274
289
|
}
|
|
275
290
|
/**
|
|
276
291
|
* 🚨 A WARNED CHOICE THAT ANSWERS WITHOUT A REQUIRED KEY FAILS PLAINLY.
|
|
@@ -333,6 +348,10 @@ export interface AdoptedAgentJsonOptions {
|
|
|
333
348
|
onResult?: HeadlessAgentJsonOptions["onResult"];
|
|
334
349
|
/** Stop waiting and harvest — same contract as `HeadlessAgentJsonOptions.signal`. */
|
|
335
350
|
signal?: AbortSignal;
|
|
351
|
+
/** Same contract as `HeadlessAgentJsonOptions.onAwaitingPerson`. */
|
|
352
|
+
onAwaitingPerson?: HeadlessAgentJsonOptions["onAwaitingPerson"];
|
|
353
|
+
/** Same contract as `HeadlessAgentJsonOptions.personWaitMs`. */
|
|
354
|
+
personWaitMs?: number;
|
|
336
355
|
/** Per-feature user-facing failure copy. */
|
|
337
356
|
failureMessages?: HeadlessAgentJsonOptions["failureMessages"];
|
|
338
357
|
/** See `deferNoJsonCapture` on `HeadlessAgentJsonOptions`. */
|
|
@@ -8,10 +8,17 @@ import {
|
|
|
8
8
|
selectExtractedJson,
|
|
9
9
|
selectFirstExtractedObject,
|
|
10
10
|
selectJsonExtractionComplete,
|
|
11
|
+
selectRequestAwaitingPerson,
|
|
11
12
|
selectRequestError,
|
|
12
13
|
selectRequestStatus,
|
|
13
14
|
selectRenderBlocksByType
|
|
14
15
|
} from "../active-requests/active-requests.selectors.js";
|
|
16
|
+
import {
|
|
17
|
+
selectLatestAnswerText as selectCommittedAnswerText,
|
|
18
|
+
selectLatestAssistantMessageId
|
|
19
|
+
} from "../messages/messages.selectors.js";
|
|
20
|
+
import { countOpenAsksForConversation } from "../../../runtime-reconnect/parked-on-person.js";
|
|
21
|
+
import { rereadAndFollow } from "../../../runtime-reconnect/reread-and-follow.js";
|
|
15
22
|
import {
|
|
16
23
|
selectLatestAnswerText,
|
|
17
24
|
selectLatestRequestId
|
|
@@ -44,6 +51,10 @@ function safeShape(err) {
|
|
|
44
51
|
const DEFAULT_TIMEOUT_MS = 12e4;
|
|
45
52
|
const DEFAULT_POLL_MS = 250;
|
|
46
53
|
const DEFAULT_SETTLE_MS = 6e3;
|
|
54
|
+
const DEFAULT_PERSON_WAIT_MS = 6 * 60 * 6e4;
|
|
55
|
+
const RECONNECT_WAIT_MS = 5 * 6e4;
|
|
56
|
+
const isConnectionLoss = (errorType) => errorType === "transport_lost" || errorType === "heartbeat_timeout";
|
|
57
|
+
const PERSON_ASK_POLL_MS = 1e4;
|
|
47
58
|
const DEFAULT_MESSAGES = {
|
|
48
59
|
streamError: "The agent failed before returning a result.",
|
|
49
60
|
noJson: "The agent finished but produced no structured JSON.",
|
|
@@ -243,6 +254,8 @@ async function adoptHeadlessAgentJson(dispatch, getState, opts) {
|
|
|
243
254
|
msgs,
|
|
244
255
|
expect: opts.expect ?? "json",
|
|
245
256
|
...opts.signal ? { signal: opts.signal } : {},
|
|
257
|
+
...opts.onAwaitingPerson ? { onAwaitingPerson: opts.onAwaitingPerson } : {},
|
|
258
|
+
personWaitMs: opts.personWaitMs ?? DEFAULT_PERSON_WAIT_MS,
|
|
246
259
|
deferNoJsonCapture: opts.deferNoJsonCapture === true
|
|
247
260
|
});
|
|
248
261
|
} catch (err) {
|
|
@@ -388,6 +401,8 @@ async function launchAndWait(dispatch, getState, opts) {
|
|
|
388
401
|
msgs,
|
|
389
402
|
expect: opts.expect ?? "json",
|
|
390
403
|
...opts.signal ? { signal: opts.signal } : {},
|
|
404
|
+
...opts.onAwaitingPerson ? { onAwaitingPerson: opts.onAwaitingPerson } : {},
|
|
405
|
+
personWaitMs: opts.personWaitMs ?? DEFAULT_PERSON_WAIT_MS,
|
|
391
406
|
deferNoJsonCapture: opts.deferNoJsonCapture === true
|
|
392
407
|
});
|
|
393
408
|
} catch (err) {
|
|
@@ -549,13 +564,45 @@ async function waitForExtraction(dispatch, getState, args) {
|
|
|
549
564
|
...base()
|
|
550
565
|
};
|
|
551
566
|
};
|
|
567
|
+
const answerSince = (state) => {
|
|
568
|
+
if (!state.messages) return `live\0${selectLatestAnswerText(conversationId)(state)}`;
|
|
569
|
+
const committed = selectCommittedAnswerText(conversationId)(state);
|
|
570
|
+
if (committed.trim()) return `${selectLatestAssistantMessageId(conversationId)(state) ?? ""}\0${committed}`;
|
|
571
|
+
return `live\0${selectLatestAnswerText(conversationId)(state)}`;
|
|
572
|
+
};
|
|
573
|
+
const unanswered = (why) => ({
|
|
574
|
+
success: false,
|
|
575
|
+
data: null,
|
|
576
|
+
error: why === "timeout" ? "Your agent's question was not answered in time." : "Stopped waiting for your answer.",
|
|
577
|
+
awaitingPerson: true,
|
|
578
|
+
...base()
|
|
579
|
+
});
|
|
580
|
+
const startMarker = answerSince(getState());
|
|
581
|
+
let lostAt = null;
|
|
582
|
+
const reconnectedAnswer = () => {
|
|
583
|
+
const marker = answerSince(getState());
|
|
584
|
+
if (marker === startMarker) return null;
|
|
585
|
+
return fuzzyFallback(marker.slice(marker.indexOf("\0") + 1));
|
|
586
|
+
};
|
|
587
|
+
let person = null;
|
|
552
588
|
try {
|
|
553
|
-
while (Date.now() - start < args.timeoutMs) {
|
|
589
|
+
while (person ? Date.now() - person.since < args.personWaitMs : Date.now() - start < args.timeoutMs || lostAt !== null && Date.now() - lostAt < RECONNECT_WAIT_MS) {
|
|
554
590
|
if (args.signal?.aborted) {
|
|
555
|
-
return settle("aborted", noResultMsg);
|
|
591
|
+
return person ? unanswered("aborted") : settle("aborted", noResultMsg);
|
|
556
592
|
}
|
|
557
593
|
const state = getState();
|
|
558
594
|
const status = selectRequestStatus(requestId)(state);
|
|
595
|
+
if (lostAt !== null) {
|
|
596
|
+
const recovered = reconnectedAnswer();
|
|
597
|
+
if (recovered != null) return { success: true, data: recovered, ...base() };
|
|
598
|
+
}
|
|
599
|
+
if (status === "error" && isConnectionLoss(selectRequestError(requestId)(state)?.error_type)) {
|
|
600
|
+
lostAt ??= Date.now();
|
|
601
|
+
if (Date.now() - lostAt < RECONNECT_WAIT_MS) {
|
|
602
|
+
await sleep(args.pollMs);
|
|
603
|
+
continue;
|
|
604
|
+
}
|
|
605
|
+
}
|
|
559
606
|
if (status === "error") {
|
|
560
607
|
const reqError = selectRequestError(requestId)(state);
|
|
561
608
|
const { data } = resolveRunData(getState, requestId, conversationId);
|
|
@@ -572,6 +619,44 @@ async function waitForExtraction(dispatch, getState, args) {
|
|
|
572
619
|
...base()
|
|
573
620
|
};
|
|
574
621
|
}
|
|
622
|
+
if (!person && status !== void 0 && TERMINAL_STATUSES.has(status) && selectRequestAwaitingPerson(requestId)(state)) {
|
|
623
|
+
person = {
|
|
624
|
+
since: Date.now(),
|
|
625
|
+
baseline: answerSince(state),
|
|
626
|
+
askedAt: Date.now(),
|
|
627
|
+
following: false,
|
|
628
|
+
changedAt: null
|
|
629
|
+
};
|
|
630
|
+
try {
|
|
631
|
+
args.onAwaitingPerson?.({ requestId, conversationId });
|
|
632
|
+
} catch (err) {
|
|
633
|
+
console.error("[runHeadlessAgentJson] onAwaitingPerson threw", err);
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
if (person) {
|
|
637
|
+
const now = Date.now();
|
|
638
|
+
if (!person.following && now - person.askedAt >= PERSON_ASK_POLL_MS) {
|
|
639
|
+
person.askedAt = now;
|
|
640
|
+
try {
|
|
641
|
+
if (await countOpenAsksForConversation(conversationId) === 0) {
|
|
642
|
+
person.following = true;
|
|
643
|
+
await rereadAndFollow(dispatch, conversationId, "runHeadlessAgentJson: the ask closed");
|
|
644
|
+
}
|
|
645
|
+
} catch {
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
const now2 = getState();
|
|
649
|
+
const marker = answerSince(now2);
|
|
650
|
+
const answer = marker.slice(marker.indexOf("\0") + 1);
|
|
651
|
+
if (answer.trim() && marker !== person.baseline) {
|
|
652
|
+
const data = fuzzyFallback(answer);
|
|
653
|
+
if (data != null) return { success: true, data, ...base() };
|
|
654
|
+
person.changedAt ??= now;
|
|
655
|
+
if (now - person.changedAt > args.settleMs) return settle("stream-ended", noResultMsg);
|
|
656
|
+
}
|
|
657
|
+
await sleep(args.pollMs);
|
|
658
|
+
continue;
|
|
659
|
+
}
|
|
575
660
|
if (selectJsonExtractionComplete(requestId)(state)) {
|
|
576
661
|
return settle("extraction-complete", noResultMsg);
|
|
577
662
|
}
|
|
@@ -586,6 +671,18 @@ async function waitForExtraction(dispatch, getState, args) {
|
|
|
586
671
|
}
|
|
587
672
|
await sleep(args.pollMs);
|
|
588
673
|
}
|
|
674
|
+
if (person) return unanswered("timeout");
|
|
675
|
+
if (lostAt !== null && selectRequestStatus(requestId)(getState()) === "error") {
|
|
676
|
+
const reqError = selectRequestError(requestId)(getState());
|
|
677
|
+
const { data } = resolveRunData(getState, requestId, conversationId);
|
|
678
|
+
return {
|
|
679
|
+
success: false,
|
|
680
|
+
data,
|
|
681
|
+
error: reqError?.user_message ?? reqError?.message ?? msgs.streamError,
|
|
682
|
+
...reqError?.error_type ? { errorDetail: reqError.error_type } : {},
|
|
683
|
+
...base()
|
|
684
|
+
};
|
|
685
|
+
}
|
|
589
686
|
return settle("timeout", msgs.timeout);
|
|
590
687
|
} finally {
|
|
591
688
|
dispatch(releaseRequestForViewer({ requestId, viewerId }));
|
|
@@ -5,6 +5,7 @@ import { useState, useEffect, useLayoutEffect, useMemo, useCallback, useRef } fr
|
|
|
5
5
|
import { cn } from "@ai-matrx/design-system";
|
|
6
6
|
import { WIDE_FIGURE_HOST_CLASS, WIDE_FIGURE_PROSE_CLIP_CLASS } from "../../agents/components/shared/assistant-message-layout.js";
|
|
7
7
|
import { splitContentIntoBlocksV2 } from "@ai-matrx/rich-content/display/markdown-classification/processors/utils/content-splitter-v2";
|
|
8
|
+
import { isWaitingForFirstContent } from "./waiting-for-content.js";
|
|
8
9
|
import { renderSettledFromRecord, settledOneShotBlocks } from "@ai-matrx/rich-content/display/chat-markdown/settle-stream-blocks";
|
|
9
10
|
import { expandTextBlocksInList } from "@ai-matrx/rich-content/display/markdown-classification/processors/utils/expand-text-blocks";
|
|
10
11
|
import { reuseUnchangedBlocks } from "@ai-matrx/rich-content/display/chat-markdown/stable-blocks";
|
|
@@ -316,13 +317,19 @@ const EnhancedChatMarkdownInternal = ({
|
|
|
316
317
|
const currentContent = editedContent ?? resolvedContent;
|
|
317
318
|
const hasRequestOrTaskId = requestId || taskId;
|
|
318
319
|
const hasReceivedNonTextContent = serverProcessedBlocks && serverProcessedBlocks.length > 0 || hasReduxRenderBlocks;
|
|
319
|
-
const isWaitingForContent = hasRequestOrTaskId && !resolvedContent.trim() && !hasReceivedNonTextContent;
|
|
320
|
-
const hasUnifiedSpecial = !settledFromRecord && (streamSlotStart !== void 0 || streamSlotEnd !== void 0 || agentCallId !== void 0 || unifiedSlots.some(
|
|
321
|
-
(s) => s.kind === "tool" || s.kind === "status" || s.kind === "error" || s.kind === "thinking" || s.kind === "render_block" && blockCarriesDataNotText(renderBlocksMap[s.blockId])
|
|
322
|
-
));
|
|
323
320
|
const hasDbInterleavedSpecial = messageInterleavedContent.some(
|
|
324
321
|
(s) => s.type === "db_tool" || s.type === "thinking"
|
|
325
322
|
);
|
|
323
|
+
const isWaitingForContent = isWaitingForFirstContent({
|
|
324
|
+
hasRequestOrTaskId: !!hasRequestOrTaskId,
|
|
325
|
+
resolvedContent,
|
|
326
|
+
hasReceivedNonTextContent: !!hasReceivedNonTextContent,
|
|
327
|
+
settledFromRecord,
|
|
328
|
+
recordHasNonText: hasDbInterleavedSpecial
|
|
329
|
+
});
|
|
330
|
+
const hasUnifiedSpecial = !settledFromRecord && (streamSlotStart !== void 0 || streamSlotEnd !== void 0 || agentCallId !== void 0 || unifiedSlots.some(
|
|
331
|
+
(s) => s.kind === "tool" || s.kind === "status" || s.kind === "error" || s.kind === "thinking" || s.kind === "render_block" && blockCarriesDataNotText(renderBlocksMap[s.blockId])
|
|
332
|
+
));
|
|
326
333
|
const toolLifecycleMapSelector = useMemo(
|
|
327
334
|
() => requestId ? selectToolLifecycleMap(requestId) : () => void 0,
|
|
328
335
|
[requestId]
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Is this assistant turn still waiting for its first content (the "Processing…" shimmer)?
|
|
3
|
+
*
|
|
4
|
+
* A turn that ENDED on a tool call with no text — an `ask_person` parked on the person — is
|
|
5
|
+
* settled: its record holds the call, and the call is what the person must see. Before this rule
|
|
6
|
+
* the empty text kept the shimmer up forever over the question it was hiding (the Applet
|
|
7
|
+
* builder, live 2026-10-09: "Processing…" while the server waited on a choose_one ask).
|
|
8
|
+
*/
|
|
9
|
+
export declare function isWaitingForFirstContent(args: {
|
|
10
|
+
hasRequestOrTaskId: boolean;
|
|
11
|
+
resolvedContent: string;
|
|
12
|
+
hasReceivedNonTextContent: boolean;
|
|
13
|
+
settledFromRecord: boolean;
|
|
14
|
+
recordHasNonText: boolean;
|
|
15
|
+
}): boolean;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
function isWaitingForFirstContent(args) {
|
|
2
|
+
if (!args.hasRequestOrTaskId) return false;
|
|
3
|
+
if (args.resolvedContent.trim()) return false;
|
|
4
|
+
if (args.hasReceivedNonTextContent) return false;
|
|
5
|
+
if (args.settledFromRecord && args.recordHasNonText) return false;
|
|
6
|
+
return true;
|
|
7
|
+
}
|
|
8
|
+
export {
|
|
9
|
+
isWaitingForFirstContent
|
|
10
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/chat",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.23",
|
|
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 explicit per-module subpaths @ai-matrx/chat/<domain>/<module> (no wildcards: scripts/public-modules.json) over a host contract (/host, /host/react) whose only required value is a db. One chat, one renderer: the old kernel entries (., /external-store, /matrx, /react, /tools, styles.css, tokens.css) are retired.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -4681,25 +4681,25 @@
|
|
|
4681
4681
|
"server-only": "^0.0.1",
|
|
4682
4682
|
"uuid": "^14.0.2",
|
|
4683
4683
|
"zod": "^4.6.5",
|
|
4684
|
+
"@ai-matrx/associations": "latest",
|
|
4684
4685
|
"@ai-matrx/browser-audio": "latest",
|
|
4686
|
+
"@ai-matrx/alchemy": "latest",
|
|
4685
4687
|
"@ai-matrx/canvas": "latest",
|
|
4686
|
-
"@ai-matrx/associations": "latest",
|
|
4687
4688
|
"@ai-matrx/content-ir": "latest",
|
|
4688
|
-
"@ai-matrx/
|
|
4689
|
-
"@ai-matrx/
|
|
4689
|
+
"@ai-matrx/content-ir-react": "latest",
|
|
4690
|
+
"@ai-matrx/data": "latest",
|
|
4690
4691
|
"@ai-matrx/design-system": "latest",
|
|
4692
|
+
"@ai-matrx/diff": "latest",
|
|
4693
|
+
"@ai-matrx/icons": "latest",
|
|
4691
4694
|
"@ai-matrx/kit": "latest",
|
|
4692
4695
|
"@ai-matrx/media": "latest",
|
|
4693
4696
|
"@ai-matrx/print": "latest",
|
|
4694
|
-
"@ai-matrx/diff": "latest",
|
|
4695
4697
|
"@ai-matrx/realtime": "latest",
|
|
4696
4698
|
"@ai-matrx/records": "latest",
|
|
4697
4699
|
"@ai-matrx/records-ui": "latest",
|
|
4698
4700
|
"@ai-matrx/rich-content": "latest",
|
|
4699
|
-
"@ai-matrx/data": "latest",
|
|
4700
4701
|
"@ai-matrx/rich-editor": "latest",
|
|
4701
|
-
"@ai-matrx/
|
|
4702
|
-
"@ai-matrx/icons": "latest"
|
|
4702
|
+
"@ai-matrx/agents": "latest"
|
|
4703
4703
|
},
|
|
4704
4704
|
"devDependencies": {
|
|
4705
4705
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
@@ -4818,5 +4818,5 @@
|
|
|
4818
4818
|
"check:side-effects": "node ../scripts/check-side-effects-listed.mjs . && node ../scripts/check-side-effects-listed.mjs --self-test",
|
|
4819
4819
|
"check:public-surface": "node ./scripts/sync-public-surface.mjs --check && node ./scripts/sync-public-surface.mjs --self-test"
|
|
4820
4820
|
},
|
|
4821
|
-
"gitHead": "
|
|
4821
|
+
"gitHead": "39aa4a6200282fa60c92b648157a3627a13b5083"
|
|
4822
4822
|
}
|