@ai-matrx/chat 0.4.10 → 0.4.12
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 +36 -0
- package/dist/agents/components/context-items/bodies/ContextInputBody.js +1 -1
- package/dist/agents/components/context-items/bodies/GenericBody.js +1 -1
- package/dist/agents/components/conversation-actions/conversation-verbs.js +1 -1
- package/dist/agents/components/inputs/smart-input/RunSkillPicker.js +1 -1
- package/dist/agents/components/live-run/LiveRunDisplay.js +1 -1
- package/dist/agents/components/live-run/LiveRunProgress.js +1 -1
- package/dist/agents/components/live-run/RunSetDisplay.js +1 -1
- package/dist/agents/components/messages-display/assistant/AgentAssistantMessage.js +2 -2
- package/dist/agents/components/messages-display/assistant/InPlaceAnswerEditor.js +1 -1
- package/dist/agents/components/messages-display/conversation-tools/find-in-conversation.js +1 -1
- package/dist/agents/components/messages-display/message-options/buildTaskSeedFromMessage.js +1 -1
- package/dist/agents/components/messages-display/user/AgentUserMessage.js +1 -1
- package/dist/agents/components/messages-display/user/FirstTurnVariables.js +1 -1
- package/dist/agents/components/run/AgentStatusIndicator.js +1 -1
- package/dist/agents/components/run/RunJobWorkingLine.js +1 -1
- package/dist/agents/components/shared/AgentNewRunButton.js +1 -1
- package/dist/agents/components/shared/AgentPlanningIndicator.js +1 -1
- package/dist/agents/conversation-export/conversation-transfer.js +1 -1
- package/dist/agents/conversation-export/document-markdown.js +1 -1
- package/dist/agents/hooks/useConversationRoutePromotion.js +1 -1
- package/dist/agents/hooks/useModelControls.js +1 -1
- package/dist/agents/redux/agent-definition/converters.js +1 -1
- package/dist/agents/redux/agent-definition/slice.js +1 -1
- package/dist/agents/redux/conversation-list/conversation-list.thunks.js +1 -1
- package/dist/agents/redux/execution-system/active-requests/active-requests.selectors.js +1 -1
- package/dist/agents/redux/execution-system/instance-context/sync-canvas-item-context.thunk.js +1 -1
- package/dist/agents/redux/execution-system/thunks/process-stream.js +1 -1
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.d.ts +7 -0
- package/dist/agents/redux/execution-system/thunks/run-ai-stream.js +13 -0
- package/dist/agents/redux/execution-system/utils/assemble-cx-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/normalize-content-blocks.js +1 -1
- package/dist/agents/redux/execution-system/utils/output-contract-guard.js +1 -1
- package/dist/agents/redux/execution-system/utils/stream-block-accumulator.js +8 -8
- package/dist/agents/utils/canvasItemContext.js +1 -1
- package/dist/canvas/workspace/ChatPanelTitleMenu.js +1 -1
- package/dist/canvas/workspace/useCanvasWorkspaceConversation.js +1 -1
- package/dist/cx-chat/components/SsrSidebarChats.js +1 -1
- package/dist/cx-chat/components/core/ChatConversationClient.js +1 -1
- package/dist/cx-chat/components/messages/AssistantMessage.js +1 -1
- package/dist/cx-chat/hooks/useInstanceBootstrap.js +1 -1
- package/dist/cx-conversation/AssistantMessage.js +1 -1
- package/dist/mandates/llm-params.d.ts +1 -1
- package/dist/mandates/output-contract.js +1 -1
- package/dist/mandates/service.d.ts +1 -1
- package/dist/mandates/service.js +1 -1
- package/dist/mandates/test-run-core.js +1 -1
- package/dist/public-chat/components/PublicMessageOptionsMenu.js +1 -1
- package/dist/surfaces/services/surface-config.service.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallBatch.js +1 -1
- package/dist/tool-call-visualization/components/ToolCallVisualization.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/AgentCallInline.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/CollabCallCard.js +1 -1
- package/dist/tool-call-visualization/renderers/agent-call/collab-subtitle.js +3 -3
- package/dist/tool-call-visualization/renderers/skill/SkillInline.js +1 -1
- package/dist/tool-call-visualization/result-fields/KeyValueGrid.js +1 -1
- package/dist/tool-call-visualization/result-fields/ResultValue.js +1 -1
- package/dist/tool-call-visualization/result-fields/shape.js +1 -1
- package/dist/tool-call-visualization/utils/cxToolCallToLifecycleEntry.js +2 -2
- package/dist/tool-call-visualization/utils/human-copy.js +3 -3
- package/dist/ui/mandates-storage/provision-shapes.d.ts +1 -1
- package/dist/ui/mandates-storage/provision-shapes.js +1 -1
- package/dist/ui/markdown-stream/EnhancedChatMarkdown.js +1 -1
- package/dist/ui/treatment-shape.d.ts +1 -1
- package/dist/ui/treatment-shape.js +1 -1
- package/dist/voice-agent/relay/useVoiceRelaySession.js +1 -1
- package/package.json +23 -6
- package/dist/agents/hooks/useWarmAgent.d.ts +0 -8
- package/dist/agents/hooks/useWarmAgent.js +0 -25
- package/dist/agents/utils/artifactId.d.ts +0 -34
- package/dist/agents/utils/artifactId.js +0 -15
- package/dist/ui/ShimmerText.d.ts +0 -5
- package/dist/ui/ShimmerText.js +0 -21
- package/dist/ui/addressWithoutNavigating.d.ts +0 -68
- package/dist/ui/addressWithoutNavigating.js +0 -60
- package/dist/utils/content-ir/decision-answers-ids.d.ts +0 -3
- package/dist/utils/content-ir/decision-answers-ids.js +0 -6
- package/dist/utils/content-ir/envelope-parity.d.ts +0 -12
- package/dist/utils/content-ir/envelope-parity.js +0 -32
- package/dist/utils/content-ir/instance-title.d.ts +0 -26
- package/dist/utils/content-ir/instance-title.js +0 -39
- package/dist/utils/content-ir/kinds/kind-markdown-utils.d.ts +0 -84
- package/dist/utils/content-ir/kinds/kind-markdown-utils.js +0 -233
- package/dist/utils/content-ir/kinds/kind-value-markdown.d.ts +0 -5
- package/dist/utils/content-ir/kinds/kind-value-markdown.js +0 -17
- package/dist/utils/content-ir/legacy-quiz-envelope.d.ts +0 -3
- package/dist/utils/content-ir/legacy-quiz-envelope.js +0 -45
- package/dist/utils/content-ir/surfaces/embedded-kind-json.d.ts +0 -140
- package/dist/utils/content-ir/surfaces/embedded-kind-json.js +0 -527
- package/dist/utils/content-ir/surfaces/json-kind-signal.d.ts +0 -307
- package/dist/utils/content-ir/surfaces/json-kind-signal.js +0 -945
- package/dist/utils/content-ir/surfaces/kind-image-alt.d.ts +0 -27
- package/dist/utils/content-ir/surfaces/kind-image-alt.js +0 -117
- package/dist/utils/content-ir/surfaces/kind-one-line.d.ts +0 -67
- package/dist/utils/content-ir/surfaces/kind-one-line.js +0 -209
- package/dist/utils/content-ir/surfaces/kind-text-label.d.ts +0 -20
- package/dist/utils/content-ir/surfaces/kind-text-label.js +0 -50
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.d.ts +0 -47
- package/dist/utils/content-ir/surfaces/kind-text-to-markdown.js +0 -399
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.d.ts +0 -54
- package/dist/utils/content-ir/surfaces/markdown-escaped-kind.js +0 -128
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.d.ts +0 -61
- package/dist/utils/content-ir/surfaces/quoted-kind-lift.js +0 -215
- package/dist/utils/inline-decision/decision-options.d.ts +0 -21
- package/dist/utils/inline-decision/decision-options.js +0 -32
- package/dist/utils/json.d.ts +0 -63
- package/dist/utils/json.js +0 -22
- package/dist/utils/markdown/plain-title.d.ts +0 -25
- package/dist/utils/markdown/plain-title.js +0 -51
- package/dist/utils/rendered-find.d.ts +0 -9
- package/dist/utils/rendered-find.js +0 -68
- package/dist/utils/rich-editor/core/caret-context.d.ts +0 -24
- package/dist/utils/rich-editor/core/caret-context.js +0 -73
- package/dist/utils/rich-editor/in-place/caret-handoff.d.ts +0 -3
- package/dist/utils/rich-editor/in-place/caret-handoff.js +0 -15
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared plumbing for kind → markdown export facets (`toMarkdown`).
|
|
3
|
-
*
|
|
4
|
-
* The FORWARD leg of the artifact ⇄ markdown two-way layer: every facet
|
|
5
|
-
* turns a kind's ZERO-LOSS value object into clean human-readable markdown
|
|
6
|
-
* (headings / lists / bold — never a JSON dump), following two laws:
|
|
7
|
-
*
|
|
8
|
-
* 1. `__kind` discriminators are transport metadata — never rendered.
|
|
9
|
-
* 2. Nothing silently vanishes: keys a facet doesn't understand (plus the
|
|
10
|
-
* declared `additionalDetails` bag every top-level kind schema carries)
|
|
11
|
-
* are appended under a small "Additional details" key: value section via
|
|
12
|
-
* `collectExtras` + `additionalDetailsSection`.
|
|
13
|
-
*
|
|
14
|
-
* `genericKindMarkdown` is the fallback for kinds WITHOUT a `toMarkdown`
|
|
15
|
-
* facet (and for unregistered kinds): readable markdown built from the value
|
|
16
|
-
* itself — headings, bold-label lists, tables — never a JSON dump.
|
|
17
|
-
*/
|
|
18
|
-
export declare function isRecordValue(value: unknown): value is Record<string, unknown>;
|
|
19
|
-
/**
|
|
20
|
-
* One-line rendering of an arbitrary value for key: value lists. Scalars
|
|
21
|
-
* render as text, scalar arrays join with ", ", anything structural falls
|
|
22
|
-
* back to inline JSON in a code span (zero loss, still one line).
|
|
23
|
-
*/
|
|
24
|
-
export declare function formatInlineValue(value: unknown): string;
|
|
25
|
-
/**
|
|
26
|
-
* Collect the keys a facet does NOT understand. Skips `__kind`,
|
|
27
|
-
* null/undefined, and the facet's known keys; merges the contents of a
|
|
28
|
-
* declared `additionalDetails` object bag (the schema-blessed extras
|
|
29
|
-
* channel) into the same flat map so both extra channels surface together.
|
|
30
|
-
*/
|
|
31
|
-
export declare function collectExtras(value: Record<string, unknown>, knownKeys: Iterable<string>): Record<string, unknown>;
|
|
32
|
-
/**
|
|
33
|
-
* A field's own name, as words — `violations_not_fixed` → "Violations not
|
|
34
|
-
* fixed", `wordCountAfter` → "Word count after".
|
|
35
|
-
*
|
|
36
|
-
* 🚨 WALK 18, DEFECT D. The finished Masterwork deliverable an Expert hands a
|
|
37
|
-
* customer carried `violations_not_fixed: []` — a key out of a schema we
|
|
38
|
-
* declared, printed at a person. A label is the one place a field name is
|
|
39
|
-
* GUARANTEED to reach a reader, so the resolution lives here, beside the
|
|
40
|
-
* extras plumbing, for every RENDERER that puts a structured field on a
|
|
41
|
-
* screen: underscores and camel humps become spaces, the first letter is
|
|
42
|
-
* capitalised, and nothing else changes.
|
|
43
|
-
*
|
|
44
|
-
* Deliberately NOT applied inside {@link extrasList}. That list is the
|
|
45
|
-
* markdown/EXPORT leg (`features/canvas/export/exportArtifactMarkdown.ts`
|
|
46
|
-
* writes a file somebody — or something — reads back), and a key spelled as
|
|
47
|
-
* prose cannot be read back as a key. A screen resolves; a file keeps the key.
|
|
48
|
-
*/
|
|
49
|
-
export declare function plainFieldLabel(key: string): string;
|
|
50
|
-
/** Render extras as a key: value bullet list (no heading). Null when empty. */
|
|
51
|
-
export declare function extrasList(extras: Record<string, unknown>): string | null;
|
|
52
|
-
/**
|
|
53
|
-
* The canonical "Additional details" section — appended at the END of a
|
|
54
|
-
* kind's markdown so nothing silently vanishes. Null when there is nothing
|
|
55
|
-
* to say (callers filter with `joinBlocks`).
|
|
56
|
-
*/
|
|
57
|
-
export declare function additionalDetailsSection(extras: Record<string, unknown>, headingLevel?: "##" | "###" | "####"): string | null;
|
|
58
|
-
/** Join markdown blocks with blank lines, dropping empty/null ones. */
|
|
59
|
-
export declare function joinBlocks(blocks: Array<string | null | undefined>): string;
|
|
60
|
-
/** "flashcard_set" → "Flashcard Set"; "Artifact" when there is nothing to say. */
|
|
61
|
-
export declare function humanizeKind(kind: string): string;
|
|
62
|
-
/** Renders a nested kind value as markdown (the registry's converter). */
|
|
63
|
-
export type NestedKindMarkdown = (value: Record<string, unknown>) => string;
|
|
64
|
-
/**
|
|
65
|
-
* Fallback markdown for kinds with no `toMarkdown` facet (or unregistered
|
|
66
|
-
* kinds): READABLE markdown built from the value itself (kind-never-raw,
|
|
67
|
-
* Arman 2026-09-30 — a kind is never shown as raw JSON, an export included).
|
|
68
|
-
* Heading = the instance title (`deriveInstanceTitle`), then the kind's
|
|
69
|
-
* name; scalar fields as a bold-label list; arrays of uniform scalar records
|
|
70
|
-
* as a table, other arrays as nested lists; nested plain objects as
|
|
71
|
-
* sections; nested KINDS through `nested` (the registry converter —
|
|
72
|
-
* `kindValueToMarkdown` passes itself; default: this function). Never the
|
|
73
|
-
* `__kind` key, never a JSON fence. Every field still appears (zero loss in
|
|
74
|
-
* content; the discriminator is named in words by the subtitle).
|
|
75
|
-
*/
|
|
76
|
-
export declare function genericKindMarkdown(kind: string, value: Record<string, unknown>, nested?: NestedKindMarkdown): string;
|
|
77
|
-
/**
|
|
78
|
-
* Readable markdown for a value that is NOT itself a kind — a kindless JSON
|
|
79
|
-
* wrapper around kinds, or a run of plain values beside kinds in an array —
|
|
80
|
-
* so a destination (export, copy) never prints it as JSON. Same rendering as
|
|
81
|
-
* a kind's body in {@link genericKindMarkdown} (bold-label scalars, tables for
|
|
82
|
-
* uniform records, nested lists, sections), nested kinds through `nested`.
|
|
83
|
-
*/
|
|
84
|
-
export declare function plainValueMarkdown(value: unknown, nested?: NestedKindMarkdown): string;
|
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
import { KIND_KEY } from "@ai-matrx/content-ir";
|
|
2
|
-
import {
|
|
3
|
-
deriveInstanceTitle,
|
|
4
|
-
INSTANCE_TITLE_KEYS
|
|
5
|
-
} from "../instance-title.js";
|
|
6
|
-
import { humanizeIdentifier } from "@ai-matrx/kit/text-case";
|
|
7
|
-
function isRecordValue(value) {
|
|
8
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
9
|
-
}
|
|
10
|
-
function isScalar(value) {
|
|
11
|
-
return typeof value === "string" || typeof value === "number" || typeof value === "boolean";
|
|
12
|
-
}
|
|
13
|
-
function formatInlineValue(value) {
|
|
14
|
-
if (value === null || value === void 0) return "\u2014";
|
|
15
|
-
if (isScalar(value)) return String(value);
|
|
16
|
-
if (Array.isArray(value) && value.every(isScalar)) {
|
|
17
|
-
return value.map(String).join(", ");
|
|
18
|
-
}
|
|
19
|
-
try {
|
|
20
|
-
return `\`${JSON.stringify(stripKindForDisplay(value))}\``;
|
|
21
|
-
} catch {
|
|
22
|
-
return String(value);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
function stripKindForDisplay(value) {
|
|
26
|
-
if (Array.isArray(value)) return value.map(stripKindForDisplay);
|
|
27
|
-
if (isRecordValue(value)) {
|
|
28
|
-
const out = {};
|
|
29
|
-
for (const [key, child] of Object.entries(value)) {
|
|
30
|
-
if (key === KIND_KEY) continue;
|
|
31
|
-
out[key] = stripKindForDisplay(child);
|
|
32
|
-
}
|
|
33
|
-
return out;
|
|
34
|
-
}
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
function collectExtras(value, knownKeys) {
|
|
38
|
-
const known = new Set(knownKeys);
|
|
39
|
-
known.add(KIND_KEY);
|
|
40
|
-
known.add("additionalDetails");
|
|
41
|
-
const extras = {};
|
|
42
|
-
const details = value.additionalDetails;
|
|
43
|
-
if (isRecordValue(details)) {
|
|
44
|
-
for (const [key, child] of Object.entries(details)) {
|
|
45
|
-
if (key === KIND_KEY || child === null || child === void 0) continue;
|
|
46
|
-
extras[key] = child;
|
|
47
|
-
}
|
|
48
|
-
} else if (details !== null && details !== void 0) {
|
|
49
|
-
extras.additionalDetails = details;
|
|
50
|
-
}
|
|
51
|
-
for (const [key, child] of Object.entries(value)) {
|
|
52
|
-
if (known.has(key) || child === null || child === void 0) continue;
|
|
53
|
-
extras[key] = child;
|
|
54
|
-
}
|
|
55
|
-
return extras;
|
|
56
|
-
}
|
|
57
|
-
function plainFieldLabel(key) {
|
|
58
|
-
const words = key.replace(/([a-z0-9])([A-Z])/g, "$1 $2").replace(/[_-]+/g, " ").trim().toLowerCase();
|
|
59
|
-
if (!words) return key;
|
|
60
|
-
return words.charAt(0).toUpperCase() + words.slice(1);
|
|
61
|
-
}
|
|
62
|
-
function extrasList(extras) {
|
|
63
|
-
const entries = Object.entries(extras);
|
|
64
|
-
if (entries.length === 0) return null;
|
|
65
|
-
return entries.map(([key, value]) => `- **${key}:** ${formatInlineValue(value)}`).join("\n");
|
|
66
|
-
}
|
|
67
|
-
function additionalDetailsSection(extras, headingLevel = "##") {
|
|
68
|
-
const list = extrasList(extras);
|
|
69
|
-
if (!list) return null;
|
|
70
|
-
return `${headingLevel} Additional details
|
|
71
|
-
|
|
72
|
-
${list}`;
|
|
73
|
-
}
|
|
74
|
-
function joinBlocks(blocks) {
|
|
75
|
-
return blocks.map((block) => typeof block === "string" ? block.trim() : "").filter((block) => block.length > 0).join("\n\n");
|
|
76
|
-
}
|
|
77
|
-
function humanizeKind(kind) {
|
|
78
|
-
return humanizeIdentifier(kind) || "Artifact";
|
|
79
|
-
}
|
|
80
|
-
function isKindValue(value) {
|
|
81
|
-
return isRecordValue(value) && typeof value[KIND_KEY] === "string" && value[KIND_KEY].trim().length > 0;
|
|
82
|
-
}
|
|
83
|
-
function scalarText(value) {
|
|
84
|
-
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
85
|
-
return String(value);
|
|
86
|
-
}
|
|
87
|
-
function cellText(value) {
|
|
88
|
-
return scalarText(value).replace(/\r?\n/g, " ").replace(/\|/g, "\\|");
|
|
89
|
-
}
|
|
90
|
-
function visibleEntries(value) {
|
|
91
|
-
return Object.entries(value).filter(
|
|
92
|
-
([key, child]) => key !== KIND_KEY && child !== null && child !== void 0 && !(typeof child === "string" && child.trim() === "") && !(Array.isArray(child) && child.length === 0)
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
function uniformTable(items) {
|
|
96
|
-
if (items.length === 0) return null;
|
|
97
|
-
let columns = null;
|
|
98
|
-
for (const item of items) {
|
|
99
|
-
if (!isRecordValue(item) || isKindValue(item)) return null;
|
|
100
|
-
const keys = Object.keys(item).filter((key) => key !== KIND_KEY);
|
|
101
|
-
if (keys.length === 0) return null;
|
|
102
|
-
if (!keys.every((key) => item[key] === null || isScalar(item[key]))) return null;
|
|
103
|
-
if (columns === null) columns = keys;
|
|
104
|
-
else if (keys.length !== columns.length || !keys.every((k, i) => k === columns[i]))
|
|
105
|
-
return null;
|
|
106
|
-
}
|
|
107
|
-
const cols = columns;
|
|
108
|
-
const head = `| ${cols.map(plainFieldLabel).join(" | ")} |`;
|
|
109
|
-
const rule = `| ${cols.map(() => "---").join(" | ")} |`;
|
|
110
|
-
const rows = items.map(
|
|
111
|
-
(item) => `| ${cols.map((key) => {
|
|
112
|
-
const cell = item[key];
|
|
113
|
-
return cell === null || cell === void 0 ? "\u2014" : cellText(cell);
|
|
114
|
-
}).join(" | ")} |`
|
|
115
|
-
);
|
|
116
|
-
return [head, rule, ...rows].join("\n");
|
|
117
|
-
}
|
|
118
|
-
function indentBlock(text, indent) {
|
|
119
|
-
return text.split("\n").map((line) => line.trim() ? indent + line : line).join("\n");
|
|
120
|
-
}
|
|
121
|
-
function listLines(value, indent, nested) {
|
|
122
|
-
if (Array.isArray(value)) {
|
|
123
|
-
const lines = [];
|
|
124
|
-
for (const item of value) {
|
|
125
|
-
if (item === null || item === void 0) continue;
|
|
126
|
-
if (isScalar(item)) lines.push(`${indent}- ${scalarText(item)}`);
|
|
127
|
-
else if (isKindValue(item)) {
|
|
128
|
-
lines.push(`${indent}-`);
|
|
129
|
-
lines.push(indentBlock(nested(item), indent + " "));
|
|
130
|
-
} else if (Array.isArray(item)) {
|
|
131
|
-
lines.push(`${indent}-`);
|
|
132
|
-
lines.push(...listLines(item, indent + " ", nested));
|
|
133
|
-
} else if (isRecordValue(item)) {
|
|
134
|
-
const fields = listLines(item, indent + " ", nested);
|
|
135
|
-
if (fields.length > 0) {
|
|
136
|
-
lines.push(`${indent}- ${fields[0].trimStart().replace(/^- /, "")}`);
|
|
137
|
-
lines.push(...fields.slice(1));
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
return lines;
|
|
142
|
-
}
|
|
143
|
-
if (isRecordValue(value)) {
|
|
144
|
-
if (isKindValue(value)) return [indentBlock(nested(value), indent)];
|
|
145
|
-
const lines = [];
|
|
146
|
-
for (const [key, child] of visibleEntries(value)) {
|
|
147
|
-
const label = `**${plainFieldLabel(key)}:**`;
|
|
148
|
-
if (isScalar(child)) lines.push(`${indent}- ${label} ${scalarText(child)}`);
|
|
149
|
-
else if (Array.isArray(child) && child.every(isScalar))
|
|
150
|
-
lines.push(`${indent}- ${label} ${child.map(scalarText).join(", ")}`);
|
|
151
|
-
else {
|
|
152
|
-
lines.push(`${indent}- ${label}`);
|
|
153
|
-
lines.push(...listLines(child, indent + " ", nested));
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
return lines;
|
|
157
|
-
}
|
|
158
|
-
return isScalar(value) ? [`${indent}- ${scalarText(value)}`] : [];
|
|
159
|
-
}
|
|
160
|
-
function headingFor(depth) {
|
|
161
|
-
return "#".repeat(Math.min(Math.max(depth, 1), 6));
|
|
162
|
-
}
|
|
163
|
-
function recordBody(value, depth, nested, skipKey) {
|
|
164
|
-
const scalars = [];
|
|
165
|
-
const sections = [];
|
|
166
|
-
for (const [key, child] of visibleEntries(value)) {
|
|
167
|
-
if (key === skipKey) continue;
|
|
168
|
-
const label = plainFieldLabel(key);
|
|
169
|
-
if (isScalar(child)) {
|
|
170
|
-
scalars.push(`- **${label}:** ${scalarText(child)}`);
|
|
171
|
-
} else if (Array.isArray(child) && child.every(isScalar)) {
|
|
172
|
-
scalars.push(`- **${label}:** ${child.map(scalarText).join(", ")}`);
|
|
173
|
-
} else if (isKindValue(child)) {
|
|
174
|
-
sections.push(joinBlocks([`${headingFor(depth + 1)} ${label}`, nested(child)]));
|
|
175
|
-
} else if (Array.isArray(child)) {
|
|
176
|
-
sections.push(
|
|
177
|
-
joinBlocks([
|
|
178
|
-
`${headingFor(depth + 1)} ${label}`,
|
|
179
|
-
uniformTable(child) ?? listLines(child, "", nested).join("\n")
|
|
180
|
-
])
|
|
181
|
-
);
|
|
182
|
-
} else if (isRecordValue(child)) {
|
|
183
|
-
sections.push(
|
|
184
|
-
joinBlocks([
|
|
185
|
-
`${headingFor(depth + 1)} ${label}`,
|
|
186
|
-
...recordBody(child, depth + 1, nested, null)
|
|
187
|
-
])
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
return [scalars.length ? scalars.join("\n") : null, ...sections].filter(
|
|
192
|
-
(block) => block !== null
|
|
193
|
-
);
|
|
194
|
-
}
|
|
195
|
-
function titleSourceKey(value, title) {
|
|
196
|
-
if (!title) return null;
|
|
197
|
-
for (const key of INSTANCE_TITLE_KEYS) {
|
|
198
|
-
const v = value[key];
|
|
199
|
-
if (typeof v === "string" && v.trim() === title) return key;
|
|
200
|
-
}
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
function genericKindMarkdown(kind, value, nested) {
|
|
204
|
-
const renderNested = nested ?? ((child) => genericKindMarkdown(String(child[KIND_KEY] ?? "artifact"), child));
|
|
205
|
-
const title = deriveInstanceTitle(value);
|
|
206
|
-
return joinBlocks([
|
|
207
|
-
`# ${title ?? humanizeKind(kind)}`,
|
|
208
|
-
`*${humanizeKind(kind)}*`,
|
|
209
|
-
...recordBody(value, 1, renderNested, titleSourceKey(value, title))
|
|
210
|
-
]);
|
|
211
|
-
}
|
|
212
|
-
function plainValueMarkdown(value, nested) {
|
|
213
|
-
const renderNested = nested ?? ((child) => genericKindMarkdown(String(child[KIND_KEY] ?? "artifact"), child));
|
|
214
|
-
if (value === null || value === void 0) return "";
|
|
215
|
-
if (isKindValue(value)) return renderNested(value);
|
|
216
|
-
if (Array.isArray(value)) {
|
|
217
|
-
return uniformTable(value) ?? listLines(value, "", renderNested).join("\n");
|
|
218
|
-
}
|
|
219
|
-
if (isRecordValue(value)) return joinBlocks(recordBody(value, 1, renderNested, null));
|
|
220
|
-
return isScalar(value) ? scalarText(value) : String(value);
|
|
221
|
-
}
|
|
222
|
-
export {
|
|
223
|
-
additionalDetailsSection,
|
|
224
|
-
collectExtras,
|
|
225
|
-
extrasList,
|
|
226
|
-
formatInlineValue,
|
|
227
|
-
genericKindMarkdown,
|
|
228
|
-
humanizeKind,
|
|
229
|
-
isRecordValue,
|
|
230
|
-
joinBlocks,
|
|
231
|
-
plainFieldLabel,
|
|
232
|
-
plainValueMarkdown
|
|
233
|
-
};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
type KindValueToMarkdown = (value: Record<string, unknown>, fallbackKind?: string) => string;
|
|
2
|
-
/** The host's registry-backed converter (matrx-frontend: `features/canvas/export/exportArtifactMarkdown`). */
|
|
3
|
-
export declare function registerKindValueMarkdown(impl: KindValueToMarkdown | null): void;
|
|
4
|
-
export declare function kindValueToMarkdown(value: Record<string, unknown>, fallbackKind?: string): string;
|
|
5
|
-
export {};
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { readObjectKind } from "@ai-matrx/content-ir";
|
|
2
|
-
import { reportUnregisteredHostSlot } from "../../../host/diagnostics.js";
|
|
3
|
-
import { genericKindMarkdown } from "./kind-markdown-utils.js";
|
|
4
|
-
let registered = null;
|
|
5
|
-
function registerKindValueMarkdown(impl) {
|
|
6
|
-
registered = impl;
|
|
7
|
-
}
|
|
8
|
-
function kindValueToMarkdown(value, fallbackKind = "artifact") {
|
|
9
|
-
if (registered) return registered(value, fallbackKind);
|
|
10
|
-
reportUnregisteredHostSlot("kindValueMarkdown", "kind values render through the generic readable form, not the host's kind registry");
|
|
11
|
-
const nested = (child) => kindValueToMarkdown(child);
|
|
12
|
-
return genericKindMarkdown(readObjectKind(value) ?? fallbackKind, value, nested);
|
|
13
|
-
}
|
|
14
|
-
export {
|
|
15
|
-
kindValueToMarkdown,
|
|
16
|
-
registerKindValueMarkdown
|
|
17
|
-
};
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import type { CanonicalBlockIR } from "@ai-matrx/content-ir";
|
|
2
|
-
/** Mirror the server's legacy quiz adapter while keeping source aliases in IR residue. */
|
|
3
|
-
export declare function canonicalizeCompletedLegacyQuizEnvelope(envelope: CanonicalBlockIR, sourceText: string): CanonicalBlockIR;
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
function isRecord(value) {
|
|
2
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3
|
-
}
|
|
4
|
-
function canonicalizeCompletedLegacyQuizEnvelope(envelope, sourceText) {
|
|
5
|
-
if (envelope.root.kind !== "quiz_set" || envelope.root.status !== "complete") {
|
|
6
|
-
return envelope;
|
|
7
|
-
}
|
|
8
|
-
let source;
|
|
9
|
-
try {
|
|
10
|
-
source = JSON.parse(sourceText);
|
|
11
|
-
} catch {
|
|
12
|
-
return envelope;
|
|
13
|
-
}
|
|
14
|
-
if (!isRecord(source)) return envelope;
|
|
15
|
-
const hasLegacyAliases = typeof source.quiz_title === "string" || typeof source.quizTitle === "string" || Array.isArray(source.multiple_choice) || Array.isArray(source.multipleChoice);
|
|
16
|
-
if (source.__kind !== void 0 || !hasLegacyAliases) return envelope;
|
|
17
|
-
const title = typeof source.quiz_title === "string" ? source.quiz_title : typeof source.quizTitle === "string" ? source.quizTitle : null;
|
|
18
|
-
const sourceQuestions = source.questions ?? source.multiple_choice ?? source.multipleChoice;
|
|
19
|
-
if (title === null || !Array.isArray(sourceQuestions)) return envelope;
|
|
20
|
-
const questions = sourceQuestions.flatMap((candidate) => {
|
|
21
|
-
if (!isRecord(candidate)) return [];
|
|
22
|
-
const { __kind: _legacyKind, ...legacyQuestion } = candidate;
|
|
23
|
-
const options = Array.isArray(candidate.options) ? candidate.options : [];
|
|
24
|
-
const answer = candidate.correct_answer ?? candidate.correctAnswer ?? "";
|
|
25
|
-
const correctAnswer = typeof answer === "number" && Number.isInteger(answer) && answer >= 0 && answer < options.length ? options[answer] : answer;
|
|
26
|
-
return [{
|
|
27
|
-
...legacyQuestion,
|
|
28
|
-
type: typeof candidate.type === "string" ? candidate.type : "multiple_choice",
|
|
29
|
-
question: typeof candidate.question === "string" ? candidate.question : "",
|
|
30
|
-
options,
|
|
31
|
-
correct_answer: typeof correctAnswer === "string" ? correctAnswer : String(correctAnswer),
|
|
32
|
-
explanation: typeof candidate.explanation === "string" ? candidate.explanation : null
|
|
33
|
-
}];
|
|
34
|
-
});
|
|
35
|
-
return {
|
|
36
|
-
...envelope,
|
|
37
|
-
root: {
|
|
38
|
-
...envelope.root,
|
|
39
|
-
value: { ...envelope.root.value, title, questions }
|
|
40
|
-
}
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
export {
|
|
44
|
-
canonicalizeCompletedLegacyQuizEnvelope
|
|
45
|
-
};
|
|
@@ -1,140 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Recover complete self-described kind objects from ANY containing text.
|
|
3
|
-
*
|
|
4
|
-
* Markdown, code fences, and XML are arrival containers, not type authority.
|
|
5
|
-
* Once a complete JSON object directly declares a non-empty `__kind`, that
|
|
6
|
-
* object is its own Content IR region even when an outer parser already
|
|
7
|
-
* classified the surrounding bytes as code, XML, or prose.
|
|
8
|
-
*
|
|
9
|
-
* Generic XML opts into literal-context exclusion so tag attributes, code,
|
|
10
|
-
* comments, and CDATA remain examples owned by their container. Otherwise the
|
|
11
|
-
* scanner is syntax-agnostic about the outer container. It only promotes candidates that independently pass JSON.parse and carry a
|
|
12
|
-
* direct string discriminator. Failed/malformed candidates remain untouched.
|
|
13
|
-
*/
|
|
14
|
-
export interface EmbeddedKindJsonRegion {
|
|
15
|
-
start: number;
|
|
16
|
-
end: number;
|
|
17
|
-
content: string;
|
|
18
|
-
kind: string;
|
|
19
|
-
}
|
|
20
|
-
export type EmbeddedKindJsonPiece = {
|
|
21
|
-
type: "container";
|
|
22
|
-
content: string;
|
|
23
|
-
} | {
|
|
24
|
-
type: "kind";
|
|
25
|
-
content: string;
|
|
26
|
-
kind: string;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* JSON punctuation that only held kinds together — the `[`, `,` and `]` of
|
|
30
|
-
* an array of kinds. Kept so the partition stays lossless; never rendered
|
|
31
|
-
* (a lone `[` drawn as a JSON card is noise, not content — A6).
|
|
32
|
-
*/
|
|
33
|
-
| {
|
|
34
|
-
type: "chrome";
|
|
35
|
-
content: string;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* The non-kind DATA of a JSON wrapper around kinds (`{"result":{…kind…},
|
|
39
|
-
* "note":"x"}`, A7): `content` is the source span it replaces (lossless),
|
|
40
|
-
* `json` is the wrapper's value with every kind removed — valid JSON, drawn
|
|
41
|
-
* as genuine JSON. A wrapper that holds only kinds has no residual piece.
|
|
42
|
-
*/
|
|
43
|
-
| {
|
|
44
|
-
type: "residual";
|
|
45
|
-
content: string;
|
|
46
|
-
json: string;
|
|
47
|
-
};
|
|
48
|
-
/**
|
|
49
|
-
* For every `{` / `[` in `text`: the end (exclusive) of the string-aware
|
|
50
|
-
* balanced JSON value opening there, or -1 (never balances). Each opener's
|
|
51
|
-
* reading starts outside a string, exactly as if read alone; one right-to-left
|
|
52
|
-
* pass reuses each nested opener's own answer (its reading from inside an
|
|
53
|
-
* enclosing value is the same reading), so the whole table is linear — a
|
|
54
|
-
* reading per opener was quadratic on thousands of unclosed `{` (round 11, P5).
|
|
55
|
-
*/
|
|
56
|
-
export declare function balancedEnds(text: string): Int32Array;
|
|
57
|
-
/** Outermost complete self-described objects, in source order. */
|
|
58
|
-
export { frontMatterEnd } from "./json-kind-signal.js";
|
|
59
|
-
export interface EmbeddedKindSearchOptions {
|
|
60
|
-
/** Generic XML: code, comments, CDATA and tags are literal (the XML card shows them). */
|
|
61
|
-
excludeLiteralContexts?: boolean;
|
|
62
|
-
/**
|
|
63
|
-
* With `excludeLiteralContexts` (an XML TAG — structure, ruling (b) round 3):
|
|
64
|
-
* a ```json / ```jsonc / ```json5 / unlabelled fence is NOT literal. A kind
|
|
65
|
-
* that is its whole body leaves with the fence's own lines as chrome, so
|
|
66
|
-
* the XML pieces around it hold no orphan fence marker.
|
|
67
|
-
*/
|
|
68
|
-
liftJsonFences?: boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Markdown: inline code spans and non-JSON fences are the model quoting
|
|
71
|
-
* source (`quotedSourceRanges`, the owner's ruling 2026-09-30) — never lifted.
|
|
72
|
-
*/
|
|
73
|
-
excludeQuotedSource?: boolean;
|
|
74
|
-
}
|
|
75
|
-
export declare function findEmbeddedKindJsonRegions(source: string, options?: EmbeddedKindSearchOptions): EmbeddedKindJsonRegion[];
|
|
76
|
-
/** Losslessly partition a container around every recovered kind region. */
|
|
77
|
-
export declare function splitAroundEmbeddedKindJson(source: string, options?: EmbeddedKindSearchOptions): EmbeddedKindJsonPiece[];
|
|
78
|
-
/**
|
|
79
|
-
* A recovered PROSE piece, shaped exactly as the live stream shapes the same
|
|
80
|
-
* bytes (A5, 2026-09-30): the stream splits `Here: {"__kind":…} after` into
|
|
81
|
-
* three lines as it arrives, so its prose blocks are trimmed at the end (every
|
|
82
|
-
* text block is) and, after a kind, start where the next character does — the
|
|
83
|
-
* spaces after the object and the one line break that ended its line are the
|
|
84
|
-
* boundary, not content. Both hosts call this on every text piece, so a live
|
|
85
|
-
* message and its reload draw the same blocks.
|
|
86
|
-
*/
|
|
87
|
-
export declare function normalizeRecoveredProsePiece(content: string, followsKind: boolean): string;
|
|
88
|
-
/**
|
|
89
|
-
* Every recovered container piece, by its container's block type: prose by
|
|
90
|
-
* the rule above, code byte-verbatim, and a SECTION (`thinking`, `info`, …)
|
|
91
|
-
* trimmed — the live stream splits a kind out of a section as it arrives
|
|
92
|
-
* (A8) and each part is a section body, which is trimmed like a whole one.
|
|
93
|
-
*/
|
|
94
|
-
export declare function normalizeRecoveredContainerPiece(content: string, containerType: string, followsKind: boolean): string;
|
|
95
|
-
/**
|
|
96
|
-
* A complete JSON value (object or array) that holds at least one kind, as
|
|
97
|
-
* one region: a recovered kind region widened to the OUTERMOST complete,
|
|
98
|
-
* parseable JSON value that contains it — a kindless wrapper
|
|
99
|
-
* (`{"result":{…kind…},"note":…}`, A7) or an array of kinds and plain values.
|
|
100
|
-
* For DESTINATION transforms (export, copy, speech) that convert the value
|
|
101
|
-
* whole; the renderer partitions the same bytes with
|
|
102
|
-
* {@link splitAroundEmbeddedKindJson}. Built on THE region finder above.
|
|
103
|
-
*/
|
|
104
|
-
export interface KindCarryingJsonRegion {
|
|
105
|
-
start: number;
|
|
106
|
-
end: number;
|
|
107
|
-
content: string;
|
|
108
|
-
value: unknown;
|
|
109
|
-
}
|
|
110
|
-
export declare function findKindCarryingJsonValues(source: string, options?: {
|
|
111
|
-
excludeLiteralContexts?: boolean;
|
|
112
|
-
}): KindCarryingJsonRegion[];
|
|
113
|
-
/**
|
|
114
|
-
* A kind that can never complete as written: [start, end) and the text of
|
|
115
|
-
* its region. Two shapes, by the same ownership rule as the finder above:
|
|
116
|
-
* - a CLOSED object whose root declares `__kind` but does not parse (the
|
|
117
|
-
* finder's malformed owner) — bounded;
|
|
118
|
-
* - an UNCLOSED JSON object or array at the tail (a stream cut off, a
|
|
119
|
-
* truncated store) holding a `"__kind"` key anywhere — runs to the end,
|
|
120
|
-
* from its outermost opener (a kindless wrapper is cut with its kind).
|
|
121
|
-
* For destinations that must say "<Kind> did not finish" instead of printing
|
|
122
|
-
* the fragment. Complete values (kind or not) are skipped whole.
|
|
123
|
-
*/
|
|
124
|
-
export interface BrokenKindJsonRegion {
|
|
125
|
-
start: number;
|
|
126
|
-
end: number;
|
|
127
|
-
content: string;
|
|
128
|
-
}
|
|
129
|
-
/**
|
|
130
|
-
* Round 10 (C1): a broken region is bounded by its OWN JSON grammar. An opener
|
|
131
|
-
* owns a kind key only when its grammar reaches the key; it runs to the end of
|
|
132
|
-
* the text only while it is still validly open, else it ends at its cut. A
|
|
133
|
-
* stray `[[`, `{"`, `{{`, `["`, an unrelated earlier object or a pasted
|
|
134
|
-
* schema never extends a region over the prose after it. A balanced span that
|
|
135
|
-
* does not parse is a region only when it reads once trailing commas go.
|
|
136
|
-
* Linear: key positions once, each opener's grammar stops at its break.
|
|
137
|
-
*/
|
|
138
|
-
export declare function findBrokenKindJsonRegions(source: string, options?: {
|
|
139
|
-
excludeLiteralContexts?: boolean;
|
|
140
|
-
}): BrokenKindJsonRegion[];
|