@ai-matrx/chat 0.5.4 → 0.5.6
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 +67 -0
- package/dist/agents/components/chat/ChatIncognitoHeaderButton.js +1 -1
- package/dist/agents/components/chat/SandboxPanel.js +1 -1
- package/dist/agents/components/context-items/context-item-block-types.d.ts +1 -1
- package/dist/agents/components/context-items/context-item-block-types.js +2 -1
- package/dist/agents/components/context-items/registry.js +9 -0
- package/dist/agents/components/conversation-history/ConversationHistorySidebar.js +1 -1
- package/dist/agents/components/inputs/resources/SmartAgentResourceChips.js +4 -1
- package/dist/agents/components/inputs/resources/useAttachRenderedArtifact.d.ts +20 -0
- package/dist/agents/components/inputs/resources/useAttachRenderedArtifact.js +107 -0
- package/dist/agents/components/inputs/smart-input/composer/ComposerAgentPill.js +135 -204
- package/dist/agents/components/inputs/smart-input/composer/already-answering.d.ts +1 -1
- package/dist/agents/components/inputs/smart-input/composer/already-answering.js +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.d.ts +1 -1
- package/dist/agents/components/inputs/smart-input/composer/useComposerAgent.js +1 -1
- package/dist/agents/components/messages-display/user/UserActionBar.js +1 -1
- package/dist/agents/components/run/AgentRunHeader.js +1 -1
- package/dist/agents/components/run/run-sidebar/SidebarHeader.js +1 -1
- package/dist/agents/components/run-controls/RunModelPicker.d.ts +5 -1
- package/dist/agents/components/run-controls/RunModelPicker.js +23 -1
- package/dist/agents/components/shared/AgentConversationColumn.js +3 -1
- package/dist/agents/components/shared/AgentHeader.js +1 -1
- package/dist/agents/components/shared/AgentHeaderMobile.js +1 -1
- package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
- package/dist/agents/components/shared/assistant-message-layout.d.ts +21 -0
- package/dist/agents/components/shared/assistant-message-layout.js +7 -1
- package/dist/agents/components/working-document/WorkingDocumentVersionHistory.js +1 -1
- package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.js +14 -0
- package/dist/agents/types/instance.types.d.ts +18 -3
- package/dist/agents/utils/renderedArtifactContext.d.ts +41 -0
- package/dist/agents/utils/renderedArtifactContext.js +41 -0
- package/dist/conversation/hooks/useDomCapturePrint.js +4 -0
- package/dist/conversation/utils/frame-print.d.ts +11 -0
- package/dist/conversation/utils/frame-print.js +46 -0
- package/dist/conversation/utils/markdown-print.d.ts +9 -1
- package/dist/conversation/utils/markdown-print.js +55 -26
- package/dist/cx-chat/components/ChatMobileHeaderBar.js +1 -1
- package/dist/cx-chat/components/ChatPanelBackButton.js +1 -1
- package/dist/cx-chat/components/ChatSidebarClient.js +1 -1
- package/dist/cx-chat/components/user-input/ConversationInput.js +2 -2
- package/dist/cx-chat/components/user-input/InputActionButtons.js +2 -2
- package/dist/host/frame-print.d.ts +17 -0
- package/dist/host/frame-print.js +13 -0
- package/dist/surfaces/components/chrome/SurfaceAgentsHeaderButton.js +1 -1
- package/dist/voice-agent/components/VoiceAgentSurface.js +2 -2
- package/package.json +6 -7
package/dist/agents/redux/execution-system/instance-resources/instance-resources.selectors.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { renderedArtifactContextEntry } from "../../../utils/renderedArtifactContext.js";
|
|
1
2
|
import { createSelector } from "@reduxjs/toolkit";
|
|
2
3
|
import {
|
|
3
4
|
isMessagePart,
|
|
@@ -445,6 +446,7 @@ function buildResourcePayload(resource) {
|
|
|
445
446
|
};
|
|
446
447
|
}
|
|
447
448
|
case "processed_document":
|
|
449
|
+
case "rendered_artifact":
|
|
448
450
|
case "source_ref":
|
|
449
451
|
case "editor_error":
|
|
450
452
|
case "editor_code_snippet":
|
|
@@ -522,6 +524,18 @@ const selectResourceContextPayload = (conversationId) => createSelector(
|
|
|
522
524
|
if (!resources) return void 0;
|
|
523
525
|
const payload = {};
|
|
524
526
|
for (const resource of Object.values(resources)) {
|
|
527
|
+
if (resource.blockType === "rendered_artifact" && resource.status === "ready") {
|
|
528
|
+
const wire = renderedArtifactContextEntry(
|
|
529
|
+
resource.source,
|
|
530
|
+
resource.options.representation
|
|
531
|
+
);
|
|
532
|
+
if (!wire) {
|
|
533
|
+
if (resource.options.representation === "screenshot") continue;
|
|
534
|
+
invalidResource(resource, "rendered artifact reference is malformed");
|
|
535
|
+
}
|
|
536
|
+
payload[wire.key] = wire.reference;
|
|
537
|
+
continue;
|
|
538
|
+
}
|
|
525
539
|
if (resource.blockType !== "processed_document" || resource.status !== "ready") {
|
|
526
540
|
continue;
|
|
527
541
|
}
|
|
@@ -354,21 +354,36 @@ export type ResourceStatus = "pending" | "resolving" | "ready" | "error";
|
|
|
354
354
|
* code editor surfaces (errors, code snippets) where the persisted user
|
|
355
355
|
* message must round-trip through the DB and re-render as chips on load.
|
|
356
356
|
*/
|
|
357
|
-
export type ResourceBlockType = "text" | "image" | "audio" | "video" | "youtube_video" | "document" | "input_webpage" | "input_notes" | "input_task" | "input_table" | "input_list" | "input_data" | "input_agent" | "input_project" | "input_agent_app" | "input_transcript" | "input_transcript_session" | "input_workbook" | "input_document" | "processed_document" | "source_ref" | "editor_error" | "editor_code_snippet" | "input_remarks";
|
|
357
|
+
export type ResourceBlockType = "text" | "image" | "audio" | "video" | "youtube_video" | "document" | "input_webpage" | "input_notes" | "input_task" | "input_table" | "input_list" | "input_data" | "input_agent" | "input_project" | "input_agent_app" | "input_transcript" | "input_transcript_session" | "input_workbook" | "input_document" | "processed_document" | "source_ref" | "editor_error" | "editor_code_snippet" | "input_remarks" | "rendered_artifact";
|
|
358
358
|
/**
|
|
359
359
|
* Which representation of a processed document is the PRIMARY one placed in the
|
|
360
360
|
* agent's context. The agent reaches the other formats (raw text, per-page,
|
|
361
361
|
* knowledge assets, PDF page images) on demand via the `document_content` tool.
|
|
362
362
|
*/
|
|
363
363
|
export type DocumentRepresentation = "clean" | "raw" | "pdf";
|
|
364
|
+
/**
|
|
365
|
+
* Representations of a rendered artifact (HTML page / canvas item). `code` is the
|
|
366
|
+
* document, `text` what a reader sees, `screenshot` the image as rendered (an
|
|
367
|
+
* explicit image part produced at attach time).
|
|
368
|
+
*/
|
|
369
|
+
export type RenderedArtifactRepresentation = "code" | "screenshot" | "text";
|
|
370
|
+
/** The representation choices, per resource type — one union, keyed by type. */
|
|
371
|
+
export interface RepresentationByResourceType {
|
|
372
|
+
processed_document: DocumentRepresentation;
|
|
373
|
+
rendered_artifact: RenderedArtifactRepresentation;
|
|
374
|
+
}
|
|
375
|
+
export type ResourceRepresentation = RepresentationByResourceType[keyof RepresentationByResourceType];
|
|
364
376
|
export interface ResourceOptions {
|
|
365
377
|
keepFresh: boolean;
|
|
366
378
|
editable: boolean;
|
|
367
379
|
convertToText: boolean;
|
|
368
380
|
optionalContext: boolean;
|
|
369
381
|
template?: "full" | "compact" | "minimal";
|
|
370
|
-
/**
|
|
371
|
-
|
|
382
|
+
/**
|
|
383
|
+
* The chosen primary representation — its legal values depend on the
|
|
384
|
+
* resource type (`RepresentationByResourceType`).
|
|
385
|
+
*/
|
|
386
|
+
representation?: ResourceRepresentation;
|
|
372
387
|
/** Per-reference file-family promotion/suppression policy. */
|
|
373
388
|
resourcePolicy?: VariableResourceContextConfig;
|
|
374
389
|
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rendered-artifact context items (rendered-output standard, guarantee 3).
|
|
3
|
+
*
|
|
4
|
+
* An HTML page or HTML canvas item is attachable to a chat turn three ways:
|
|
5
|
+
* - `code` — the document, as a resource reference (canvas_item preferred),
|
|
6
|
+
* - `text` — what a reader sees, the server resolver's `text` representation,
|
|
7
|
+
* - `screenshot` — the page as rendered, captured at ATTACH time by the host's
|
|
8
|
+
* capture port and attached as an explicit image part
|
|
9
|
+
* (`input_image`, the paste-image path). Never captured at send.
|
|
10
|
+
*
|
|
11
|
+
* `code` / `text` ride `request.context` as a resource reference
|
|
12
|
+
* (`selectResourceContextPayload`); they never become `user_input`.
|
|
13
|
+
*/
|
|
14
|
+
import { createResourceReference } from "../agent-context/resource-reference.js";
|
|
15
|
+
import type { RenderedArtifactRepresentation, ResourceRepresentation } from "../types/instance.types.js";
|
|
16
|
+
export declare const RENDERED_ARTIFACT_BLOCK_TYPE = "rendered_artifact";
|
|
17
|
+
export type RenderedArtifactRecordType = "canvas_item" | "html_page";
|
|
18
|
+
/** The `source` of a `rendered_artifact` resource. */
|
|
19
|
+
export interface RenderedArtifactSource {
|
|
20
|
+
kind: "rendered_artifact";
|
|
21
|
+
record_type: RenderedArtifactRecordType;
|
|
22
|
+
record_id: string;
|
|
23
|
+
title: string;
|
|
24
|
+
}
|
|
25
|
+
export interface RenderedArtifactRepresentationOption {
|
|
26
|
+
value: RenderedArtifactRepresentation;
|
|
27
|
+
label: string;
|
|
28
|
+
hint: string;
|
|
29
|
+
}
|
|
30
|
+
/** The options a rendered artifact offers, data-driven so a new one is one entry. */
|
|
31
|
+
export declare function availableRenderedArtifactRepresentations(): RenderedArtifactRepresentationOption[];
|
|
32
|
+
export declare function isRenderedArtifactSource(source: unknown): source is RenderedArtifactSource;
|
|
33
|
+
export declare function isRenderedArtifactRepresentation(value: unknown): value is RenderedArtifactRepresentation;
|
|
34
|
+
/**
|
|
35
|
+
* The `request.context` entry for a code/text attachment, or null when the
|
|
36
|
+
* source is malformed or the choice is `screenshot` (an image part, not context).
|
|
37
|
+
*/
|
|
38
|
+
export declare function renderedArtifactContextEntry(source: unknown, representation: ResourceRepresentation | undefined): {
|
|
39
|
+
key: string;
|
|
40
|
+
reference: ReturnType<typeof createResourceReference>;
|
|
41
|
+
} | null;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { createResourceReference } from "../agent-context/resource-reference.js";
|
|
2
|
+
const RENDERED_ARTIFACT_BLOCK_TYPE = "rendered_artifact";
|
|
3
|
+
function availableRenderedArtifactRepresentations() {
|
|
4
|
+
return [
|
|
5
|
+
{ value: "screenshot", label: "Screenshot", hint: "The page as you see it" },
|
|
6
|
+
{ value: "code", label: "Code", hint: "The full HTML document" },
|
|
7
|
+
{ value: "text", label: "Text", hint: "The words on the page" }
|
|
8
|
+
];
|
|
9
|
+
}
|
|
10
|
+
function isRenderedArtifactSource(source) {
|
|
11
|
+
if (!source || typeof source !== "object") return false;
|
|
12
|
+
const s = source;
|
|
13
|
+
return s.kind === "rendered_artifact" && (s.record_type === "canvas_item" || s.record_type === "html_page") && typeof s.record_id === "string" && s.record_id.length > 0;
|
|
14
|
+
}
|
|
15
|
+
function isRenderedArtifactRepresentation(value) {
|
|
16
|
+
return value === "code" || value === "screenshot" || value === "text";
|
|
17
|
+
}
|
|
18
|
+
function serverRepresentation(recordType, representation) {
|
|
19
|
+
if (representation === "text") return "text";
|
|
20
|
+
return recordType === "html_page" ? "html" : "content";
|
|
21
|
+
}
|
|
22
|
+
function renderedArtifactContextEntry(source, representation) {
|
|
23
|
+
if (!isRenderedArtifactSource(source)) return null;
|
|
24
|
+
const rep = isRenderedArtifactRepresentation(
|
|
25
|
+
representation
|
|
26
|
+
) ? representation : "code";
|
|
27
|
+
if (rep === "screenshot") return null;
|
|
28
|
+
return {
|
|
29
|
+
key: `resource_${source.record_type}_${source.record_id}_${rep}`,
|
|
30
|
+
reference: createResourceReference(source.record_type, source.record_id, {
|
|
31
|
+
representation: serverRepresentation(source.record_type, rep)
|
|
32
|
+
})
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
RENDERED_ARTIFACT_BLOCK_TYPE,
|
|
37
|
+
availableRenderedArtifactRepresentations,
|
|
38
|
+
isRenderedArtifactRepresentation,
|
|
39
|
+
isRenderedArtifactSource,
|
|
40
|
+
renderedArtifactContextEntry
|
|
41
|
+
};
|
|
@@ -15,9 +15,12 @@ function useDomCapturePrint() {
|
|
|
15
15
|
setProgress(0);
|
|
16
16
|
setError(null);
|
|
17
17
|
let releaseRenderAll = null;
|
|
18
|
+
let restoreFrames = null;
|
|
18
19
|
try {
|
|
19
20
|
const { renderAllDiagrams } = await import("@ai-matrx/rich-content/mermaid/lazy-draw");
|
|
20
21
|
releaseRenderAll = (await renderAllDiagrams()).release;
|
|
22
|
+
const { framesToPictures } = await import("../utils/frame-print.js");
|
|
23
|
+
restoreFrames = (await framesToPictures(el)).restore;
|
|
21
24
|
const [{ captureDocumentPdf }, { downloadFile }] = await Promise.all([
|
|
22
25
|
import("@ai-matrx/alchemy/operate/capture"),
|
|
23
26
|
import("@ai-matrx/kit/download")
|
|
@@ -36,6 +39,7 @@ function useDomCapturePrint() {
|
|
|
36
39
|
const msg = err instanceof Error ? err.message : "PDF export failed";
|
|
37
40
|
setError(msg);
|
|
38
41
|
} finally {
|
|
42
|
+
restoreFrames?.();
|
|
39
43
|
releaseRenderAll?.();
|
|
40
44
|
setIsCapturing(false);
|
|
41
45
|
setProgress(0);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Full Print's frame pre-pass (the `renderAllDiagrams` of live pages): every
|
|
3
|
+
* `<iframe>` inside the captured message is shown as its picture — from the
|
|
4
|
+
* host's frame capture port — or as an honest stand-in, for exactly as long
|
|
5
|
+
* as the capture runs. The frames are hidden, never removed (removing one
|
|
6
|
+
* reloads its page), and come back untouched when `restore` runs.
|
|
7
|
+
*/
|
|
8
|
+
export declare function framesToPictures(root: HTMLElement): Promise<{
|
|
9
|
+
restore: () => void;
|
|
10
|
+
frames: number;
|
|
11
|
+
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FRAME_PRINT_STAND_IN, getFramePrintCapture } from "../../host/frame-print.js";
|
|
2
|
+
async function framesToPictures(root) {
|
|
3
|
+
const frames = [...root.querySelectorAll("iframe")];
|
|
4
|
+
if (frames.length === 0) return { restore: () => void 0, frames: 0 };
|
|
5
|
+
const capture = getFramePrintCapture();
|
|
6
|
+
const undo = [];
|
|
7
|
+
await Promise.all(
|
|
8
|
+
frames.map(async (frame) => {
|
|
9
|
+
let src = null;
|
|
10
|
+
if (capture) {
|
|
11
|
+
try {
|
|
12
|
+
src = await capture(frame);
|
|
13
|
+
} catch (error) {
|
|
14
|
+
console.error("[print] a page could not be captured for print", error);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
const width = frame.clientWidth || frame.offsetWidth;
|
|
18
|
+
const height = frame.clientHeight || frame.offsetHeight;
|
|
19
|
+
let stand;
|
|
20
|
+
if (src) {
|
|
21
|
+
const img = document.createElement("img");
|
|
22
|
+
img.src = src;
|
|
23
|
+
img.alt = frame.title || "Web page";
|
|
24
|
+
img.style.cssText = `display:block;width:${width ? `${width}px` : "100%"};max-width:100%;height:auto`;
|
|
25
|
+
await img.decode().catch(() => void 0);
|
|
26
|
+
stand = img;
|
|
27
|
+
} else {
|
|
28
|
+
stand = document.createElement("div");
|
|
29
|
+
stand.textContent = FRAME_PRINT_STAND_IN;
|
|
30
|
+
stand.style.cssText = `display:flex;align-items:center;justify-content:center;box-sizing:border-box;width:${width ? `${width}px` : "100%"};max-width:100%;min-height:${Math.min(Math.max(height, 96), 240)}px;padding:16px;border:1px dashed #94a3b8;border-radius:8px;color:#475569;font:italic 13px/1.4 system-ui,sans-serif;text-align:center;background:#f8fafc`;
|
|
31
|
+
}
|
|
32
|
+
stand.setAttribute("data-matrx-frame-print", "");
|
|
33
|
+
const display = frame.style.display;
|
|
34
|
+
frame.style.display = "none";
|
|
35
|
+
frame.after(stand);
|
|
36
|
+
undo.push(() => {
|
|
37
|
+
stand.remove();
|
|
38
|
+
frame.style.display = display;
|
|
39
|
+
});
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
return { restore: () => undo.forEach((fn) => fn()), frames: frames.length };
|
|
43
|
+
}
|
|
44
|
+
export {
|
|
45
|
+
framesToPictures
|
|
46
|
+
};
|
|
@@ -12,5 +12,13 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Fix conversion or styling in the package (SAME-SESSION LAW), never here.
|
|
14
14
|
*/
|
|
15
|
-
import type
|
|
15
|
+
import { type PrintOutcome } from "@ai-matrx/print/core";
|
|
16
|
+
/**
|
|
17
|
+
* Prints a message: its prose through the article skin, and every embedded
|
|
18
|
+
* block through the SAME adapter its own print uses (`@ai-matrx/print`'s one
|
|
19
|
+
* block-printer registry, keyed by artifact type / `__kind`) — a quiz as its
|
|
20
|
+
* questions, a deck as its study sheet, a diagram as its drawing, an HTML page
|
|
21
|
+
* as its picture (a print window runs no author scripts; the page's own Print
|
|
22
|
+
* is the sharp one, and the person is told so).
|
|
23
|
+
*/
|
|
16
24
|
export declare function printMarkdownContent(markdown: string, title?: string): PrintOutcome | Promise<PrintOutcome>;
|
|
@@ -1,43 +1,72 @@
|
|
|
1
|
-
import { printMarkdown, printMarkdownWhenReady } from "@ai-matrx/print/markdown";
|
|
1
|
+
import { listPrintBlocks, printMarkdown, printMarkdownWhenReady } from "@ai-matrx/print/markdown";
|
|
2
|
+
import { getBlockPrinter } from "@ai-matrx/print/core";
|
|
2
3
|
import { notifyPrintOutcome } from "../../host/ui-slots.js";
|
|
3
|
-
const
|
|
4
|
+
const FRAME_BLOCK_TYPES = /* @__PURE__ */ new Set(["html", "react", "iframe"]);
|
|
5
|
+
function blockData(block) {
|
|
6
|
+
const text = block.body.trim();
|
|
7
|
+
if (text.startsWith("{") || text.startsWith("[")) {
|
|
8
|
+
try {
|
|
9
|
+
return JSON.parse(text);
|
|
10
|
+
} catch {
|
|
11
|
+
return block.body;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return block.body;
|
|
15
|
+
}
|
|
16
|
+
function adapterFor(block) {
|
|
17
|
+
const printer = getBlockPrinter(block.type);
|
|
18
|
+
return printer?.toPrintHtml ? printer : null;
|
|
19
|
+
}
|
|
4
20
|
function printMarkdownContent(markdown, title = "AI Response") {
|
|
5
|
-
|
|
21
|
+
const blocks = listPrintBlocks(markdown, "article");
|
|
22
|
+
const hasMermaid = blocks.some((block) => block.source === "fence" && block.type === "mermaid");
|
|
23
|
+
const adapted = blocks.filter((block) => adapterFor(block) !== null);
|
|
24
|
+
if (!hasMermaid && adapted.length === 0) {
|
|
6
25
|
const outcome = printMarkdown(markdown, { skin: "article", title });
|
|
7
26
|
notifyPrintOutcome(outcome);
|
|
8
27
|
return outcome;
|
|
9
28
|
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
try {
|
|
16
|
-
const { drawMermaidForPrint } = await import("@ai-matrx/rich-content/mermaid/print-render");
|
|
17
|
-
drawn = await drawMermaidForPrint(markdown);
|
|
18
|
-
} catch (error) {
|
|
19
|
-
console.error("[print] diagrams could not be drawn", error);
|
|
20
|
-
const { toast } = await import("../../host/notify.js");
|
|
21
|
-
toast.warning("Diagrams could not be drawn, so they print as source.");
|
|
22
|
-
return {};
|
|
23
|
-
}
|
|
24
|
-
const { pictures, failed } = drawn;
|
|
29
|
+
let drawing = null;
|
|
30
|
+
const drawAll = () => drawing ??= (async () => {
|
|
31
|
+
try {
|
|
32
|
+
const { drawMermaidForPrint } = await import("@ai-matrx/rich-content/mermaid/print-render");
|
|
33
|
+
const { pictures, failed } = await drawMermaidForPrint(markdown);
|
|
25
34
|
if (failed > 0) {
|
|
26
35
|
const { toast } = await import("../../host/notify.js");
|
|
27
36
|
toast.warning(
|
|
28
37
|
`${failed} diagram${failed === 1 ? "" : "s"} could not be drawn and print${failed === 1 ? "s" : ""} as source.`
|
|
29
38
|
);
|
|
30
39
|
}
|
|
31
|
-
return
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
};
|
|
40
|
+
return pictures;
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error("[print] diagrams could not be drawn", error);
|
|
43
|
+
const { toast } = await import("../../host/notify.js");
|
|
44
|
+
toast.warning("Diagrams could not be drawn, so they print as source.");
|
|
45
|
+
return null;
|
|
38
46
|
}
|
|
39
|
-
})
|
|
47
|
+
})();
|
|
48
|
+
return printMarkdownWhenReady(markdown, {
|
|
49
|
+
skin: "article",
|
|
50
|
+
title,
|
|
51
|
+
renderBlock: async (block) => {
|
|
52
|
+
if (block.source === "fence" && block.type === "mermaid") {
|
|
53
|
+
const svg = (await drawAll())?.get(block.body);
|
|
54
|
+
return svg ? { svg, alt: "Diagram" } : null;
|
|
55
|
+
}
|
|
56
|
+
const printer = adapterFor(block);
|
|
57
|
+
if (!printer?.toPrintHtml) return null;
|
|
58
|
+
return printer.toPrintHtml(blockData(block), {
|
|
59
|
+
type: block.type,
|
|
60
|
+
raw: block.body,
|
|
61
|
+
...block.title ? { title: block.title } : {}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}).then(async (outcome) => {
|
|
40
65
|
notifyPrintOutcome(outcome);
|
|
66
|
+
if (outcome === "opened" && adapted.some((block) => FRAME_BLOCK_TYPES.has(block.type))) {
|
|
67
|
+
const { toast } = await import("../../host/notify.js");
|
|
68
|
+
toast.info("Web pages print as a picture inside a message. For sharp text, print the page from its card.");
|
|
69
|
+
}
|
|
41
70
|
return outcome;
|
|
42
71
|
});
|
|
43
72
|
}
|
|
@@ -3,7 +3,7 @@ import { AppLink } from "../../host/ui-slots.js";
|
|
|
3
3
|
import {
|
|
4
4
|
MenuTapButton,
|
|
5
5
|
SquarePenTapButton
|
|
6
|
-
} from "@ai-matrx/tap-target/buttons";
|
|
6
|
+
} from "@ai-matrx/design-system/tap-target/buttons";
|
|
7
7
|
import ChatMobileAgentName from "./ChatMobileAgentName.js";
|
|
8
8
|
import ChatMobileAdminToggles from "./ChatMobileAdminToggles.js";
|
|
9
9
|
function ChatMobileHeaderBar() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
import { ChevronLeftTapButton } from "@ai-matrx/tap-target/buttons";
|
|
3
|
+
import { ChevronLeftTapButton } from "@ai-matrx/design-system/tap-target/buttons";
|
|
4
4
|
function ChatPanelBackButton() {
|
|
5
5
|
function handleBack() {
|
|
6
6
|
const panelCheckbox = document.getElementById(
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ChevronLeftTapButton,
|
|
13
13
|
PanelLeftTapButton,
|
|
14
14
|
PlusTapButton
|
|
15
|
-
} from "@ai-matrx/tap-target/buttons";
|
|
15
|
+
} from "@ai-matrx/design-system/tap-target/buttons";
|
|
16
16
|
import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
|
|
17
17
|
import { selectAgentById } from "../../agents/redux/agent-definition/selectors.js";
|
|
18
18
|
import { pushAppHref } from "../../host/ui-slots.js";
|
|
@@ -18,8 +18,8 @@ import {
|
|
|
18
18
|
Layers
|
|
19
19
|
} from "lucide-react";
|
|
20
20
|
import { ResponseModeButtons, BackToStartButton } from "./InpuControlButtons.js";
|
|
21
|
-
import { TapTargetButtonTransparent } from "@ai-matrx/tap-target";
|
|
22
|
-
import { PlusTapButton } from "@ai-matrx/tap-target/buttons";
|
|
21
|
+
import { TapTargetButtonTransparent } from "@ai-matrx/design-system/tap-target";
|
|
22
|
+
import { PlusTapButton } from "@ai-matrx/design-system/tap-target/buttons";
|
|
23
23
|
import { InputActionButtons } from "./InputActionButtons.js";
|
|
24
24
|
import { useAppSelector, useAppDispatch } from "../../../store/hooks.js";
|
|
25
25
|
import { selectIsSuperAdminDebugger } from "../../../host/prefs.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Loader2, Bug } from "lucide-react";
|
|
4
|
-
import { TapTargetButtonSolid } from "@ai-matrx/tap-target";
|
|
5
|
-
import { ArrowUpTapButton } from "@ai-matrx/tap-target/buttons";
|
|
4
|
+
import { TapTargetButtonSolid } from "@ai-matrx/design-system/tap-target";
|
|
5
|
+
import { ArrowUpTapButton } from "@ai-matrx/design-system/tap-target/buttons";
|
|
6
6
|
import { MicrophoneIconButton } from "../../../host/ui-slots.js";
|
|
7
7
|
import { Button } from "@ai-matrx/design-system/controls";
|
|
8
8
|
function InputActionButtons({
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frame-capture port for message prints.
|
|
3
|
+
*
|
|
4
|
+
* A live page inside a message (an HTML page's `<iframe>`) cannot be copied
|
|
5
|
+
* by a DOM capture — html2canvas draws a cross-origin frame blank. Full Print
|
|
6
|
+
* asks this port for a picture of each frame before it rasterizes the
|
|
7
|
+
* message; the host plugs its capture engine in (the server's real browser
|
|
8
|
+
* for a published page). Without one, the frame prints an honest stand-in,
|
|
9
|
+
* never blank and never its code.
|
|
10
|
+
*/
|
|
11
|
+
/** A picture (data URL or image URL) of exactly what the frame shows, or null when none can be made. */
|
|
12
|
+
export type FramePrintCapture = (frame: HTMLIFrameElement) => Promise<string | null>;
|
|
13
|
+
/** What prints in a frame's place when no picture can be made. */
|
|
14
|
+
export declare const FRAME_PRINT_STAND_IN = "Page image unavailable \u2014 print the page from its card.";
|
|
15
|
+
/** Plugs (or, with null, removes) the host's frame capture engine. */
|
|
16
|
+
export declare function setFramePrintCapture(capture: FramePrintCapture | null): void;
|
|
17
|
+
export declare function getFramePrintCapture(): FramePrintCapture | null;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const FRAME_PRINT_STAND_IN = "Page image unavailable \u2014 print the page from its card.";
|
|
2
|
+
const PORT = /* @__PURE__ */ Symbol.for("ai-matrx.chat.frame-print-capture");
|
|
3
|
+
function setFramePrintCapture(capture) {
|
|
4
|
+
globalThis[PORT] = capture;
|
|
5
|
+
}
|
|
6
|
+
function getFramePrintCapture() {
|
|
7
|
+
return globalThis[PORT] ?? null;
|
|
8
|
+
}
|
|
9
|
+
export {
|
|
10
|
+
FRAME_PRINT_STAND_IN,
|
|
11
|
+
getFramePrintCapture,
|
|
12
|
+
setFramePrintCapture
|
|
13
|
+
};
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useRef, useState } from "react";
|
|
4
4
|
import { SurfaceAgentsPanelImpl } from "../../../ui/lazy/SurfaceAgentsPanelImpl.js";
|
|
5
|
-
import { TapTargetButtonTransparent } from "@ai-matrx/tap-target";
|
|
5
|
+
import { TapTargetButtonTransparent } from "@ai-matrx/design-system/tap-target";
|
|
6
6
|
import { INTELLIGENCE_ICON } from "@ai-matrx/icons/domain";
|
|
7
7
|
import {
|
|
8
8
|
Popover,
|
|
@@ -3,8 +3,8 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
3
3
|
import { useEffect, useState } from "react";
|
|
4
4
|
import { useRouter } from "../../host/navigation.js";
|
|
5
5
|
import { Music2, Radio, Settings2 } from "lucide-react";
|
|
6
|
-
import { TapTargetButton } from "@ai-matrx/tap-target";
|
|
7
|
-
import { ChevronLeftTapButton } from "@ai-matrx/tap-target/buttons";
|
|
6
|
+
import { TapTargetButton } from "@ai-matrx/design-system/tap-target";
|
|
7
|
+
import { ChevronLeftTapButton } from "@ai-matrx/design-system/tap-target/buttons";
|
|
8
8
|
import { RouteHeader } from "../../host/chrome.js";
|
|
9
9
|
import { toast } from "../../host/notify.js";
|
|
10
10
|
import { useAppDispatch, useAppSelector } from "../../store/hooks.js";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-matrx/chat",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.6",
|
|
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. 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",
|
|
@@ -166,26 +166,25 @@
|
|
|
166
166
|
"server-only": "^0.0.1",
|
|
167
167
|
"uuid": "^14.0.2",
|
|
168
168
|
"zod": "^4.6.5",
|
|
169
|
-
"@ai-matrx/agents": "latest",
|
|
170
169
|
"@ai-matrx/alchemy": "latest",
|
|
171
170
|
"@ai-matrx/associations": "latest",
|
|
172
171
|
"@ai-matrx/browser-audio": "latest",
|
|
172
|
+
"@ai-matrx/agents": "latest",
|
|
173
173
|
"@ai-matrx/canvas": "latest",
|
|
174
174
|
"@ai-matrx/content-ir": "latest",
|
|
175
175
|
"@ai-matrx/content-ir-react": "latest",
|
|
176
176
|
"@ai-matrx/data": "latest",
|
|
177
|
-
"@ai-matrx/design-system": "latest",
|
|
178
177
|
"@ai-matrx/diff": "latest",
|
|
179
|
-
"@ai-matrx/
|
|
178
|
+
"@ai-matrx/icons": "latest",
|
|
180
179
|
"@ai-matrx/media": "latest",
|
|
181
180
|
"@ai-matrx/print": "latest",
|
|
182
181
|
"@ai-matrx/realtime": "latest",
|
|
183
182
|
"@ai-matrx/records": "latest",
|
|
183
|
+
"@ai-matrx/records-ui": "latest",
|
|
184
184
|
"@ai-matrx/rich-content": "latest",
|
|
185
185
|
"@ai-matrx/rich-editor": "latest",
|
|
186
|
-
"@ai-matrx/
|
|
187
|
-
"@ai-matrx/
|
|
188
|
-
"@ai-matrx/records-ui": "latest"
|
|
186
|
+
"@ai-matrx/kit": "latest",
|
|
187
|
+
"@ai-matrx/design-system": "latest"
|
|
189
188
|
},
|
|
190
189
|
"devDependencies": {
|
|
191
190
|
"@arethetypeswrong/cli": "^0.18.5",
|