@aparte/core 0.17.0 → 0.17.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -4
- package/dist/components/chat/aparte-chat.d.ts +22 -14
- package/dist/components/chat/aparte-chat.d.ts.map +1 -1
- package/dist/components/suggestions/aparte-suggestions.d.ts +27 -2
- package/dist/components/suggestions/aparte-suggestions.d.ts.map +1 -1
- package/dist/config/aparte-config.d.ts +43 -8
- package/dist/config/aparte-config.d.ts.map +1 -1
- package/dist/custom-elements.json +11854 -11630
- package/dist/{dialog-triggers-Bb-3EkT4.js → dialog-triggers-DwTGKWeU.js} +89 -9
- package/dist/dialog-triggers-DwTGKWeU.js.map +1 -0
- package/dist/generated/element-attributes.d.ts +5 -5
- package/dist/generated/element-attributes.d.ts.map +1 -1
- package/dist/index.css +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -16
- package/dist/index.js.map +1 -1
- package/dist/index.node.d.ts +1 -1
- package/dist/index.node.d.ts.map +1 -1
- package/dist/index.node.js +1 -1
- package/dist/index.node.js.map +1 -1
- package/dist/renderers/markdown-stream.d.ts.map +1 -1
- package/dist/renderers/segments/tool-call.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/tools.d.ts +14 -0
- package/dist/types/tools.d.ts.map +1 -1
- package/dist/utils/transcript.d.ts +13 -0
- package/dist/utils/transcript.d.ts.map +1 -0
- package/package.json +2 -2
- package/dist/dialog-triggers-Bb-3EkT4.js.map +0 -1
|
@@ -1318,6 +1318,7 @@ class AparteConfig {
|
|
|
1318
1318
|
// Tool Registry
|
|
1319
1319
|
_tools = /* @__PURE__ */ new Map();
|
|
1320
1320
|
_toolRenderers = /* @__PURE__ */ new Map();
|
|
1321
|
+
_toolSummaries = /* @__PURE__ */ new Map();
|
|
1321
1322
|
/** Tagged blocks the stream parser recognises in the prose — see {@link registerStreamBlock}. */
|
|
1322
1323
|
_streamBlocks = /* @__PURE__ */ new Map();
|
|
1323
1324
|
_segmentDefaults = /* @__PURE__ */ new Map();
|
|
@@ -1415,11 +1416,12 @@ class AparteConfig {
|
|
|
1415
1416
|
* Set an incremental (streaming) Markdown renderer provider. Optional —
|
|
1416
1417
|
* when set, the chat bubble uses it to render the assistant message
|
|
1417
1418
|
* token-by-token DURING streaming (incremental parse + DOM append, O(n)),
|
|
1418
|
-
* instead of re-parsing the whole string on every token.
|
|
1419
|
-
*
|
|
1420
|
-
*
|
|
1421
|
-
*
|
|
1422
|
-
*
|
|
1419
|
+
* instead of re-parsing the whole string on every token. With no one-shot
|
|
1420
|
+
* `setMarkdownProvider` registered, it also renders a COMPLETE string
|
|
1421
|
+
* (`renderMarkdown`): a restored reply, a non-streaming provider's answer, a
|
|
1422
|
+
* stored segment — so a reply renders the same however it arrived. A registered
|
|
1423
|
+
* one-shot provider takes over for those, and re-renders the finished message
|
|
1424
|
+
* at full fidelity.
|
|
1423
1425
|
*/
|
|
1424
1426
|
setStreamingMarkdownProvider(fn) {
|
|
1425
1427
|
this._streamingMarkdownProvider = fn;
|
|
@@ -2033,8 +2035,16 @@ class AparteConfig {
|
|
|
2033
2035
|
return val === void 0 ? "" : val;
|
|
2034
2036
|
}
|
|
2035
2037
|
/**
|
|
2036
|
-
* Render Markdown to HTML
|
|
2037
|
-
*
|
|
2038
|
+
* Render a complete Markdown string to HTML: the one-shot provider when one is
|
|
2039
|
+
* registered, else the incremental provider run over the whole string, else core's
|
|
2040
|
+
* default (escape + `<br>`).
|
|
2041
|
+
*
|
|
2042
|
+
* The middle step is what makes the incremental provider enough on its own. Without
|
|
2043
|
+
* it a reply rendered two ways depending on how it arrived: rich while it streamed,
|
|
2044
|
+
* escaped source once it came back complete — a restored conversation, a
|
|
2045
|
+
* non-streaming provider, a stored segment. Same parser, same sanitizer, so the two
|
|
2046
|
+
* cannot disagree. It needs a `document` to write into; without one (a server render)
|
|
2047
|
+
* the default answers, as before.
|
|
2038
2048
|
*/
|
|
2039
2049
|
renderMarkdown(raw) {
|
|
2040
2050
|
if (this._markdownProvider) {
|
|
@@ -2043,6 +2053,16 @@ class AparteConfig {
|
|
|
2043
2053
|
} catch (error) {
|
|
2044
2054
|
console.warn("[AparteConfig] Markdown provider failed, using fallback:", error);
|
|
2045
2055
|
}
|
|
2056
|
+
} else if (this._streamingMarkdownProvider && typeof document !== "undefined") {
|
|
2057
|
+
try {
|
|
2058
|
+
const target = document.createElement("div");
|
|
2059
|
+
const renderer = this._streamingMarkdownProvider(target);
|
|
2060
|
+
renderer.write(raw);
|
|
2061
|
+
renderer.end();
|
|
2062
|
+
return this.sanitizeHtml(target.innerHTML);
|
|
2063
|
+
} catch (error) {
|
|
2064
|
+
console.warn("[AparteConfig] Streaming Markdown provider failed on a complete string, using fallback:", error);
|
|
2065
|
+
}
|
|
2046
2066
|
}
|
|
2047
2067
|
return this._defaultMarkdownRenderer(raw);
|
|
2048
2068
|
}
|
|
@@ -2174,6 +2194,37 @@ class AparteConfig {
|
|
|
2174
2194
|
getToolRenderer(toolName) {
|
|
2175
2195
|
return this._toolRenderers.get(toolName);
|
|
2176
2196
|
}
|
|
2197
|
+
/**
|
|
2198
|
+
* Say what a call targets, in the default row, after the tool's name.
|
|
2199
|
+
*
|
|
2200
|
+
* The default row names the tool and keeps its arguments behind a disclosure, so a
|
|
2201
|
+
* reader saw that a file was read, not which one. Replacing the row with
|
|
2202
|
+
* `registerToolRenderer` for that one line meant re-implementing its six states,
|
|
2203
|
+
* the spinner, the disclosure and the relabel contract. This keeps all of them and
|
|
2204
|
+
* adds the line. A tool with its own renderer draws its own row, so its summary is
|
|
2205
|
+
* never read.
|
|
2206
|
+
*
|
|
2207
|
+
* The text is written as text, never parsed as HTML. It is read when the row
|
|
2208
|
+
* renders, on every update to the call (its arguments may still be arriving), and
|
|
2209
|
+
* on every config change — so registering one after a row is on screen shows up on
|
|
2210
|
+
* that row's next update.
|
|
2211
|
+
*
|
|
2212
|
+
* @example
|
|
2213
|
+
* // read_file skills.json
|
|
2214
|
+
* aparteGlobalConfig.registerToolSummary('read_file', (segment) =>
|
|
2215
|
+
* String(segment.toolCall.input['path'] ?? ''));
|
|
2216
|
+
*/
|
|
2217
|
+
registerToolSummary(toolName, summary) {
|
|
2218
|
+
this._toolSummaries.set(toolName, summary);
|
|
2219
|
+
}
|
|
2220
|
+
/** Unregister a per-tool summary. */
|
|
2221
|
+
unregisterToolSummary(toolName) {
|
|
2222
|
+
this._toolSummaries.delete(toolName);
|
|
2223
|
+
}
|
|
2224
|
+
/** Get the summary for a specific tool name. Returns undefined if none registered. */
|
|
2225
|
+
getToolSummary(toolName) {
|
|
2226
|
+
return this._toolSummaries.get(toolName);
|
|
2227
|
+
}
|
|
2177
2228
|
/**
|
|
2178
2229
|
* Teach the stream parser a tagged block: `<tag attr="…">…</tag>` in the model's
|
|
2179
2230
|
* prose becomes the segment `toSegment` builds, streamed delta by delta.
|
|
@@ -2382,6 +2433,7 @@ class AparteConfig {
|
|
|
2382
2433
|
this._fetchedModels.clear();
|
|
2383
2434
|
this._tools.clear();
|
|
2384
2435
|
this._toolRenderers.clear();
|
|
2436
|
+
this._toolSummaries.clear();
|
|
2385
2437
|
this._streamBlocks.clear();
|
|
2386
2438
|
this._modelConfig = {};
|
|
2387
2439
|
this._requireModelSelection = false;
|
|
@@ -2467,6 +2519,7 @@ function subscribeConfigChange(el2, handler) {
|
|
|
2467
2519
|
window.addEventListener(APARTE_CONFIG_CHANGE, listener);
|
|
2468
2520
|
return () => window.removeEventListener(APARTE_CONFIG_CHANGE, listener);
|
|
2469
2521
|
}
|
|
2522
|
+
const settledFromParser = /* @__PURE__ */ new WeakMap();
|
|
2470
2523
|
const ONE_SHOT_PROBE = "<i>a</i>";
|
|
2471
2524
|
function hasOneShotMarkdownProvider() {
|
|
2472
2525
|
return contextConfig().renderMarkdown(ONE_SHOT_PROBE) !== escapeHtml(ONE_SHOT_PROBE);
|
|
@@ -2474,6 +2527,7 @@ function hasOneShotMarkdownProvider() {
|
|
|
2474
2527
|
function writeStreamedMarkdown(host, contentEl, content, streaming) {
|
|
2475
2528
|
if (streaming) {
|
|
2476
2529
|
if (host._aparteSmd === void 0) {
|
|
2530
|
+
settledFromParser.delete(contentEl);
|
|
2477
2531
|
const renderer = contextConfig().createStreamingMarkdownRenderer(contentEl);
|
|
2478
2532
|
if (renderer) {
|
|
2479
2533
|
contentEl.textContent = "";
|
|
@@ -2502,9 +2556,13 @@ function writeStreamedMarkdown(host, contentEl, content, streaming) {
|
|
|
2502
2556
|
host._aparteSmd = void 0;
|
|
2503
2557
|
if (!hasOneShotMarkdownProvider()) {
|
|
2504
2558
|
contentEl.innerHTML = contextConfig().sanitizeHtml(contentEl.innerHTML);
|
|
2559
|
+
settledFromParser.set(contentEl, content);
|
|
2505
2560
|
return;
|
|
2506
2561
|
}
|
|
2562
|
+
} else if (settledFromParser.get(contentEl) === content && !hasOneShotMarkdownProvider()) {
|
|
2563
|
+
return;
|
|
2507
2564
|
}
|
|
2565
|
+
settledFromParser.delete(contentEl);
|
|
2508
2566
|
contentEl.innerHTML = contextConfig().renderMarkdown(content);
|
|
2509
2567
|
}
|
|
2510
2568
|
function highlightMarkdownFences(contentEl) {
|
|
@@ -2843,12 +2901,31 @@ function highlightParts(element) {
|
|
|
2843
2901
|
});
|
|
2844
2902
|
}
|
|
2845
2903
|
}
|
|
2904
|
+
function toolTarget(segment) {
|
|
2905
|
+
const summary = contextConfig().getToolSummary(segment.toolCall?.name ?? "");
|
|
2906
|
+
if (!summary) return "";
|
|
2907
|
+
try {
|
|
2908
|
+
const text = summary(segment);
|
|
2909
|
+
return typeof text === "string" ? text.trim() : "";
|
|
2910
|
+
} catch {
|
|
2911
|
+
return "";
|
|
2912
|
+
}
|
|
2913
|
+
}
|
|
2914
|
+
function setTarget(element, segment) {
|
|
2915
|
+
const el2 = element.querySelector(".aparte-tool-target");
|
|
2916
|
+
if (!el2) return;
|
|
2917
|
+
const text = toolTarget(segment);
|
|
2918
|
+
if (el2.textContent !== text) el2.textContent = text;
|
|
2919
|
+
el2.toggleAttribute("hidden", !text);
|
|
2920
|
+
}
|
|
2846
2921
|
function pillMarkup(segment, name, status) {
|
|
2847
2922
|
const badge = stateBadge(segment);
|
|
2923
|
+
const target = toolTarget(segment);
|
|
2848
2924
|
return `
|
|
2849
2925
|
<span class="aparte-tool-label">
|
|
2850
2926
|
<span class="aparte-tool-icon">${contextConfig().getIcon("tool")}</span>
|
|
2851
2927
|
<span class="aparte-tool-name">${escapeHtml(name)}</span>
|
|
2928
|
+
<span class="aparte-tool-target"${target ? "" : " hidden"}>${escapeHtml(target)}</span>
|
|
2852
2929
|
</span>
|
|
2853
2930
|
<span class="aparte-spinner aparte-tool-spinner" aria-hidden="true"${status === "pending" ? "" : " hidden"}></span>
|
|
2854
2931
|
<span class="aparte-tool-state">${badge}</span>`;
|
|
@@ -2913,6 +2990,7 @@ const toolCallRenderer = {
|
|
|
2913
2990
|
}
|
|
2914
2991
|
const icon = element.querySelector(".aparte-tool-icon");
|
|
2915
2992
|
if (icon) icon.innerHTML = cfg.getIcon("tool");
|
|
2993
|
+
setTarget(element, segment);
|
|
2916
2994
|
const statusEl = element.querySelector(".aparte-tool-state");
|
|
2917
2995
|
if (statusEl) statusEl.innerHTML = stateBadge(segment);
|
|
2918
2996
|
},
|
|
@@ -2953,6 +3031,7 @@ const toolCallRenderer = {
|
|
|
2953
3031
|
const badge = element.querySelector(".aparte-tool-state");
|
|
2954
3032
|
if (badge) badge.innerHTML = stateBadge(segment);
|
|
2955
3033
|
element.querySelector(".aparte-tool-spinner")?.toggleAttribute("hidden", status !== "pending");
|
|
3034
|
+
setTarget(element, segment);
|
|
2956
3035
|
setPart(element, "input", input);
|
|
2957
3036
|
setPart(element, "output", segment.result ?? "");
|
|
2958
3037
|
highlightParts(element);
|
|
@@ -6908,7 +6987,8 @@ export {
|
|
|
6908
6987
|
isTerminalStatus as ag,
|
|
6909
6988
|
adoptMessageSegments as ah,
|
|
6910
6989
|
APARTE_DERIVED_SEGMENTS as ai,
|
|
6911
|
-
|
|
6990
|
+
chatBoundaryOf as aj,
|
|
6991
|
+
rootOf as ak,
|
|
6912
6992
|
APARTE_DEFAULT_BUBBLE_ACTIONS as b,
|
|
6913
6993
|
APARTE_DEFAULT_HOST_HANDLERS as c,
|
|
6914
6994
|
APARTE_DEFAULT_ICON_FALLBACKS as d,
|
|
@@ -6935,4 +7015,4 @@ export {
|
|
|
6935
7015
|
collectRendererStyles as y,
|
|
6936
7016
|
contentToText as z
|
|
6937
7017
|
};
|
|
6938
|
-
//# sourceMappingURL=dialog-triggers-
|
|
7018
|
+
//# sourceMappingURL=dialog-triggers-DwTGKWeU.js.map
|