@artooi/ag-ui-web-component 0.39.0 → 0.41.0
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 +208 -1
- package/README.md +116 -36
- package/dist/ag-ui-web-component.bundle.js +255 -101
- package/dist/ag-ui-web-component.bundle.js.map +4 -4
- package/dist/constants.d.ts +3 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/core/ag_ui_chat.d.ts +7 -3
- package/dist/core/ag_ui_chat.d.ts.map +1 -1
- package/dist/core/agui_client.d.ts +29 -8
- package/dist/core/agui_client.d.ts.map +1 -1
- package/dist/core/attachment.d.ts +11 -4
- package/dist/core/attachment.d.ts.map +1 -1
- package/dist/core/client_seed.d.ts +14 -2
- package/dist/core/client_seed.d.ts.map +1 -1
- package/dist/core/tool_outcome.d.ts +4 -3
- package/dist/core/tool_outcome.d.ts.map +1 -1
- package/dist/core/utils.d.ts +19 -0
- package/dist/core/utils.d.ts.map +1 -1
- package/dist/index.js +1078 -664
- package/dist/index.js.map +4 -4
- package/dist/tools/tool_catalog.d.ts.map +1 -1
- package/dist/ui/composer/composer_attachments.d.ts +6 -1
- package/dist/ui/composer/composer_attachments.d.ts.map +1 -1
- package/dist/ui/composer/composer_voice.d.ts +3 -0
- package/dist/ui/composer/composer_voice.d.ts.map +1 -1
- package/dist/ui/excerpts/transcript_quote_offer.d.ts +7 -2
- package/dist/ui/excerpts/transcript_quote_offer.d.ts.map +1 -1
- package/dist/ui/history/conversation_history.d.ts +30 -4
- package/dist/ui/history/conversation_history.d.ts.map +1 -1
- package/dist/ui/placement/launcher_drag.d.ts +6 -0
- package/dist/ui/placement/launcher_drag.d.ts.map +1 -1
- package/dist/ui/placement/panel_placement.d.ts +1 -1
- package/dist/ui/placement/panel_placement.d.ts.map +1 -1
- package/dist/ui/styles.d.ts +1 -1
- package/dist/ui/styles.d.ts.map +1 -1
- package/dist/ui/transcript/transcript.d.ts +3 -2
- package/dist/ui/transcript/transcript.d.ts.map +1 -1
- package/dist/ui/ui_strings.d.ts +2 -0
- package/dist/ui/ui_strings.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/constants.ts +3 -2
- package/src/core/ag_ui_chat.ts +217 -64
- package/src/core/agui_client.ts +155 -125
- package/src/core/attachment.ts +13 -5
- package/src/core/client_seed.ts +14 -2
- package/src/core/tool_outcome.ts +4 -3
- package/src/core/utils.ts +23 -0
- package/src/tools/tool_catalog.ts +63 -12
- package/src/ui/composer/composer_attachments.ts +64 -41
- package/src/ui/composer/composer_voice.ts +5 -0
- package/src/ui/excerpts/transcript_quote_offer.ts +26 -13
- package/src/ui/history/conversation_history.ts +149 -38
- package/src/ui/placement/launcher_drag.ts +104 -89
- package/src/ui/placement/panel_placement.ts +27 -3
- package/src/ui/styles.ts +137 -14
- package/src/ui/transcript/transcript.ts +10 -5
- package/src/ui/ui_strings.ts +3 -0
- package/src/version.ts +1 -1
package/dist/index.js
CHANGED
|
@@ -929,6 +929,10 @@ function answerUnansweredCalls(messages, answer, except = /* @__PURE__ */ new Se
|
|
|
929
929
|
function toolCallIds(value) {
|
|
930
930
|
return Array.isArray(value) ? value.map((call) => Object(call).id).filter((id) => typeof id === "string") : [];
|
|
931
931
|
}
|
|
932
|
+
function metadataOrTopLevel(message, key) {
|
|
933
|
+
const metadata = Object(message.metadata);
|
|
934
|
+
return metadata[key] ?? message[key];
|
|
935
|
+
}
|
|
932
936
|
|
|
933
937
|
// src/ui/ui_strings.ts
|
|
934
938
|
var DEFAULT_UI_STRINGS = {
|
|
@@ -982,6 +986,7 @@ var DEFAULT_UI_STRINGS = {
|
|
|
982
986
|
attachmentsStillUploading: "{n} file still uploading \u2014 it was not sent with this message and is still attached.",
|
|
983
987
|
notConnected: "This chat isn\u2019t connected to an agent, so the message wasn\u2019t sent.",
|
|
984
988
|
continueNeedsTurn: "Type the next turn in the composer first, then pick a run to continue.",
|
|
989
|
+
continueWhileRunning: "Wait for the current answer or stop it, then pick a run to continue.",
|
|
985
990
|
skillNeeds: "\u201C{title}\u201D needs {fields} \u2014 fill it in below, then send.",
|
|
986
991
|
message: "Message",
|
|
987
992
|
inputPlaceholder: "Ask anything\u2026",
|
|
@@ -1418,12 +1423,12 @@ var ToolCatalog = class {
|
|
|
1418
1423
|
},
|
|
1419
1424
|
required: ["question"]
|
|
1420
1425
|
},
|
|
1421
|
-
handler: (args) => this.#askUser(args)
|
|
1426
|
+
handler: (args, callId) => this.#askUser(args, callId)
|
|
1422
1427
|
}
|
|
1423
1428
|
];
|
|
1424
1429
|
}
|
|
1425
1430
|
/** Render the `ask_user` question card and resolve with the user's answer. */
|
|
1426
|
-
async #askUser(args) {
|
|
1431
|
+
async #askUser(args, callId) {
|
|
1427
1432
|
const question = typeof args["question"] === "string" ? args["question"] : "";
|
|
1428
1433
|
const request = { question };
|
|
1429
1434
|
const rawOptions = args["options"];
|
|
@@ -1435,19 +1440,59 @@ var ToolCatalog = class {
|
|
|
1435
1440
|
}
|
|
1436
1441
|
const signal = this.#host.decision.open();
|
|
1437
1442
|
this.#host.hidePending();
|
|
1438
|
-
const
|
|
1439
|
-
const answer = renderer !== null ? (
|
|
1440
|
-
// Called on the element, as `this.askUserRenderer(...)` always was.
|
|
1441
|
-
await renderer.call(this.#host.element, request, { signal })
|
|
1442
|
-
) : await requestQuestion(this.#host.ensureGroup(), request, {
|
|
1443
|
+
const builtIn = () => requestQuestion(this.#host.ensureGroup(), request, {
|
|
1443
1444
|
signal,
|
|
1444
1445
|
strings: this.#host.strings()
|
|
1445
1446
|
});
|
|
1447
|
+
const renderer = this.#host.askUserRenderer();
|
|
1448
|
+
let answer;
|
|
1449
|
+
if (renderer === null) {
|
|
1450
|
+
answer = await builtIn();
|
|
1451
|
+
} else {
|
|
1452
|
+
try {
|
|
1453
|
+
answer = await renderer.call(this.#host.element, request, { signal });
|
|
1454
|
+
} catch (error) {
|
|
1455
|
+
answer = await this.#afterRendererFailed(error, signal, callId, builtIn);
|
|
1456
|
+
}
|
|
1457
|
+
}
|
|
1446
1458
|
this.#host.decision.close();
|
|
1447
1459
|
this.#host.updateEmptyState();
|
|
1448
1460
|
this.#host.follow();
|
|
1449
1461
|
return answer;
|
|
1450
1462
|
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Answer an `ask_user` call whose host renderer threw or rejected instead of
|
|
1465
|
+
* answering: put the question to the built-in card.
|
|
1466
|
+
*
|
|
1467
|
+
* The same answer `approvalRenderer` gets for the same failure, and for the
|
|
1468
|
+
* same reason: a renderer is presentation, not a policy. It decides how the
|
|
1469
|
+
* question looks, never whether the agent's question is put to the user.
|
|
1470
|
+
* Uncaught, the throw escaped the handler, so the call's card settled as an
|
|
1471
|
+
* error quoting the host's message, that message went on to the agent as the
|
|
1472
|
+
* tool result -- a detail of the host's page, never written for the model --
|
|
1473
|
+
* and the pending decision was never closed, so the next Stop, in whatever
|
|
1474
|
+
* round, aborted the signal of a wait that had already ended rather than
|
|
1475
|
+
* finding nothing open. The built-in card still asks,
|
|
1476
|
+
* and the run carries on as if no renderer had been set. Reported the way a
|
|
1477
|
+
* failed `render` is, and for the same reason: survived is not the same as
|
|
1478
|
+
* findable.
|
|
1479
|
+
*
|
|
1480
|
+
* Except when the wait was already abandoned. A renderer honouring its signal
|
|
1481
|
+
* rejects once a Stop fires it, which is the signal working rather than the
|
|
1482
|
+
* renderer failing, and a card drawn then would ask about a run the user just
|
|
1483
|
+
* ended. So it resolves with the empty answer the built-in card resolves with
|
|
1484
|
+
* on the same abort, and says nothing.
|
|
1485
|
+
*/
|
|
1486
|
+
#afterRendererFailed(error, signal, callId, builtIn) {
|
|
1487
|
+
if (signal.aborted) {
|
|
1488
|
+
return Promise.resolve("");
|
|
1489
|
+
}
|
|
1490
|
+
console.warn(
|
|
1491
|
+
`ag-ui-chat: askUserRenderer failed for tool call ${callId}, so the built-in question card asks instead`,
|
|
1492
|
+
error
|
|
1493
|
+
);
|
|
1494
|
+
return builtIn();
|
|
1495
|
+
}
|
|
1451
1496
|
};
|
|
1452
1497
|
|
|
1453
1498
|
// src/skills/skill_name_from.ts
|
|
@@ -2711,8 +2756,15 @@ var ComposerAttachments = class {
|
|
|
2711
2756
|
* built-in multipart endpoint: reveal the 📎 button, wire the hidden file
|
|
2712
2757
|
* input + drag-and-drop, and mount the tray. With neither, the affordance
|
|
2713
2758
|
* stays hidden and the chat degrades to text-only.
|
|
2759
|
+
*
|
|
2760
|
+
* Called on every connect, so it starts by taking down the tray the last
|
|
2761
|
+
* connection mounted: that one was disposed when the element left, and the
|
|
2762
|
+
* attributes that decide whether there is a tray at all may have changed
|
|
2763
|
+
* since. The shell outlives a connection, so its listeners go under `signal`.
|
|
2714
2764
|
*/
|
|
2715
|
-
wire() {
|
|
2765
|
+
wire(signal) {
|
|
2766
|
+
this.#tray?.element.remove();
|
|
2767
|
+
this.#tray = null;
|
|
2716
2768
|
const url = this.#host.element.getAttribute("data-attachments-url");
|
|
2717
2769
|
const upload = this.#host.uploadHandler() ?? this.#defaultUploadHandler(url);
|
|
2718
2770
|
if (upload === null) {
|
|
@@ -2734,8 +2786,8 @@ var ComposerAttachments = class {
|
|
|
2734
2786
|
this.#host.slot.appendChild(this.#tray.element);
|
|
2735
2787
|
this.#host.fileInput.accept = accept;
|
|
2736
2788
|
this.#host.button.hidden = false;
|
|
2737
|
-
this.#enableDragAndDrop();
|
|
2738
|
-
this.#enablePaste(tray);
|
|
2789
|
+
this.#enableDragAndDrop(signal);
|
|
2790
|
+
this.#enablePaste(tray, signal);
|
|
2739
2791
|
}
|
|
2740
2792
|
/** The queueing behind `AgUiChat.attachFile`, whose doc is the contract. */
|
|
2741
2793
|
attach(file) {
|
|
@@ -2779,25 +2831,37 @@ var ComposerAttachments = class {
|
|
|
2779
2831
|
return Number.isFinite(parsed) && parsed >= 0 ? parsed : DEFAULT_ATTACHMENT_MAX_BYTES;
|
|
2780
2832
|
}
|
|
2781
2833
|
/** Accept files dropped anywhere on the chat shell into the tray. */
|
|
2782
|
-
#enableDragAndDrop() {
|
|
2834
|
+
#enableDragAndDrop(signal) {
|
|
2783
2835
|
const chat = this.#host.chat;
|
|
2784
|
-
chat.addEventListener(
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2836
|
+
chat.addEventListener(
|
|
2837
|
+
"dragover",
|
|
2838
|
+
(event) => {
|
|
2839
|
+
event.preventDefault();
|
|
2840
|
+
chat.classList.add("chat--dragover");
|
|
2841
|
+
},
|
|
2842
|
+
{ signal }
|
|
2843
|
+
);
|
|
2844
|
+
chat.addEventListener(
|
|
2845
|
+
"dragleave",
|
|
2846
|
+
() => {
|
|
2847
|
+
chat.classList.remove("chat--dragover");
|
|
2848
|
+
},
|
|
2849
|
+
{ signal }
|
|
2850
|
+
);
|
|
2851
|
+
chat.addEventListener(
|
|
2852
|
+
"drop",
|
|
2853
|
+
(event) => {
|
|
2854
|
+
event.preventDefault();
|
|
2855
|
+
chat.classList.remove("chat--dragover");
|
|
2856
|
+
const files = event.dataTransfer?.files;
|
|
2857
|
+
if (files !== void 0) {
|
|
2858
|
+
for (const file of Array.from(files)) {
|
|
2859
|
+
this.#tray?.add(file);
|
|
2860
|
+
}
|
|
2798
2861
|
}
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2862
|
+
},
|
|
2863
|
+
{ signal }
|
|
2864
|
+
);
|
|
2801
2865
|
}
|
|
2802
2866
|
/**
|
|
2803
2867
|
* Turn a very long text paste into an attachment instead of a wall of text.
|
|
@@ -2867,24 +2931,28 @@ var ComposerAttachments = class {
|
|
|
2867
2931
|
* clipboard, and swallowing the words someone meant to paste in order to
|
|
2868
2932
|
* attach a picture they did not is the worse of the two failures.
|
|
2869
2933
|
*/
|
|
2870
|
-
#enablePaste(tray) {
|
|
2871
|
-
this.#host.chat.addEventListener(
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
|
|
2879
|
-
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2934
|
+
#enablePaste(tray, signal) {
|
|
2935
|
+
this.#host.chat.addEventListener(
|
|
2936
|
+
"paste",
|
|
2937
|
+
(event) => {
|
|
2938
|
+
const clipboard = event.clipboardData ?? null;
|
|
2939
|
+
if (clipboard === null) {
|
|
2940
|
+
return;
|
|
2941
|
+
}
|
|
2942
|
+
const files = Array.from(clipboard.files);
|
|
2943
|
+
if (files.length === 0) {
|
|
2944
|
+
this.#pasteLongTextAsFile(event, clipboard, tray);
|
|
2945
|
+
return;
|
|
2946
|
+
}
|
|
2947
|
+
if (clipboard.getData("text/plain") === "") {
|
|
2948
|
+
event.preventDefault();
|
|
2949
|
+
}
|
|
2950
|
+
for (const file of files) {
|
|
2951
|
+
this.#tray?.add(named(file));
|
|
2952
|
+
}
|
|
2953
|
+
},
|
|
2954
|
+
{ signal }
|
|
2955
|
+
);
|
|
2888
2956
|
}
|
|
2889
2957
|
/** Tell the host what the tray now holds — see {@link ATTACHMENT_EVENT}. */
|
|
2890
2958
|
#dispatch(tray) {
|
|
@@ -3112,8 +3180,13 @@ var ComposerVoice = class {
|
|
|
3112
3180
|
* built-in POST endpoint. The control records via `MediaRecorder` and drops
|
|
3113
3181
|
* the transcript into the composer; with neither configured the mic stays
|
|
3114
3182
|
* hidden and the chat is text-only.
|
|
3183
|
+
*
|
|
3184
|
+
* Called on every connect, so it starts by taking down the mic the last
|
|
3185
|
+
* connection mounted, which was released when the element left.
|
|
3115
3186
|
*/
|
|
3116
3187
|
wire() {
|
|
3188
|
+
this.#voice?.element.remove();
|
|
3189
|
+
this.#voice = null;
|
|
3117
3190
|
const url = this.#host.element.getAttribute("data-transcribe-url");
|
|
3118
3191
|
const transcribe = this.#host.transcribeHandler() ?? this.#defaultTranscribeHandler(url);
|
|
3119
3192
|
if (transcribe === null) {
|
|
@@ -3622,26 +3695,39 @@ ${quoted}`;
|
|
|
3622
3695
|
this.#pageQuote?.detach();
|
|
3623
3696
|
this.#pageQuote = null;
|
|
3624
3697
|
}
|
|
3625
|
-
/**
|
|
3626
|
-
|
|
3698
|
+
/**
|
|
3699
|
+
* Build the offer and listen for settled selections in the transcript.
|
|
3700
|
+
*
|
|
3701
|
+
* The button and the transcript outlive a connection, so the listeners go
|
|
3702
|
+
* under `signal`, which the element aborts when it leaves the document.
|
|
3703
|
+
*/
|
|
3704
|
+
mount(signal) {
|
|
3627
3705
|
const button2 = this.button;
|
|
3628
3706
|
button2.className = "quote-selection";
|
|
3629
3707
|
button2.type = "button";
|
|
3630
3708
|
button2.setAttribute("part", "quote-selection");
|
|
3631
3709
|
button2.textContent = this.#host.strings().quoteSelection;
|
|
3632
3710
|
button2.hidden = true;
|
|
3633
|
-
button2.addEventListener(
|
|
3634
|
-
|
|
3635
|
-
|
|
3636
|
-
|
|
3637
|
-
|
|
3638
|
-
|
|
3639
|
-
|
|
3640
|
-
|
|
3711
|
+
button2.addEventListener(
|
|
3712
|
+
"mousedown",
|
|
3713
|
+
(event) => {
|
|
3714
|
+
event.preventDefault();
|
|
3715
|
+
},
|
|
3716
|
+
{ signal }
|
|
3717
|
+
);
|
|
3718
|
+
button2.addEventListener(
|
|
3719
|
+
"click",
|
|
3720
|
+
() => {
|
|
3721
|
+
this.#host.quote(this.#quoting);
|
|
3722
|
+
window.getSelection()?.removeAllRanges();
|
|
3723
|
+
this.#hide();
|
|
3724
|
+
},
|
|
3725
|
+
{ signal }
|
|
3726
|
+
);
|
|
3641
3727
|
const messages = this.#host.messages;
|
|
3642
|
-
messages.addEventListener("mouseup", (event) => this.#onSelectionSettled(event));
|
|
3643
|
-
messages.addEventListener("keyup", () => this.#onSelectionSettled());
|
|
3644
|
-
messages.addEventListener("mousedown", () => this.#hide());
|
|
3728
|
+
messages.addEventListener("mouseup", (event) => this.#onSelectionSettled(event), { signal });
|
|
3729
|
+
messages.addEventListener("keyup", () => this.#onSelectionSettled(), { signal });
|
|
3730
|
+
messages.addEventListener("mousedown", () => this.#hide(), { signal });
|
|
3645
3731
|
}
|
|
3646
3732
|
/** Whether the transcript offers to quote what the user selects. */
|
|
3647
3733
|
#enabled() {
|
|
@@ -3927,10 +4013,11 @@ var CheckpointMenu = class {
|
|
|
3927
4013
|
|
|
3928
4014
|
// src/ui/history/conversation_history.ts
|
|
3929
4015
|
import { randomUUID as randomUUID3 } from "@ag-ui/client";
|
|
4016
|
+
import { contentToText } from "@ag-ui/core";
|
|
3930
4017
|
|
|
3931
4018
|
// src/core/attachment.ts
|
|
3932
4019
|
function messageAttachments(message) {
|
|
3933
|
-
const refs = message
|
|
4020
|
+
const refs = metadataOrTopLevel(message, "attachments");
|
|
3934
4021
|
return Array.isArray(refs) ? refs.filter(isAttachmentRef) : [];
|
|
3935
4022
|
}
|
|
3936
4023
|
function isAttachmentRef(value) {
|
|
@@ -4022,10 +4109,16 @@ var ConversationHistory = class {
|
|
|
4022
4109
|
/** The active thread's id. Empty until the element connects. */
|
|
4023
4110
|
#threadId = "";
|
|
4024
4111
|
/**
|
|
4025
|
-
* The
|
|
4026
|
-
*
|
|
4112
|
+
* The conversation as last written for the next client the element builds to
|
|
4113
|
+
* start from: what the last restore replayed, or what a checkpoint
|
|
4114
|
+
* continuation last saved after it. Emptied with the rest of the in-memory run.
|
|
4027
4115
|
*/
|
|
4028
4116
|
#restored = [];
|
|
4117
|
+
/**
|
|
4118
|
+
* Counts the conversations cleared away, so a continuation can tell whether
|
|
4119
|
+
* the one it continued is still on screen when it saves.
|
|
4120
|
+
*/
|
|
4121
|
+
#cleared = 0;
|
|
4029
4122
|
// Bumped on every rehydrate; a replay whose generation is stale (a newer
|
|
4030
4123
|
// thread switch started while it awaited a slow store) drops its result.
|
|
4031
4124
|
#generation = 0;
|
|
@@ -4043,10 +4136,14 @@ var ConversationHistory = class {
|
|
|
4043
4136
|
get threadId() {
|
|
4044
4137
|
return this.#threadId;
|
|
4045
4138
|
}
|
|
4046
|
-
/** The
|
|
4139
|
+
/** The conversation as last written, for seeding the next client. */
|
|
4047
4140
|
get restored() {
|
|
4048
4141
|
return this.#restored;
|
|
4049
4142
|
}
|
|
4143
|
+
/** The checkpoint continuation in flight, or `null` when none is running. */
|
|
4144
|
+
get continuation() {
|
|
4145
|
+
return this.#continuation;
|
|
4146
|
+
}
|
|
4050
4147
|
/** Point at the thread the store says is active. */
|
|
4051
4148
|
adoptActiveThread() {
|
|
4052
4149
|
this.#threadId = this.#host.conversationStore().threadId();
|
|
@@ -4071,6 +4168,7 @@ var ConversationHistory = class {
|
|
|
4071
4168
|
/** Forget the messages the last restore seeded, with the rest of the run. */
|
|
4072
4169
|
forgetRestored() {
|
|
4073
4170
|
this.#restored = [];
|
|
4171
|
+
this.#cleared += 1;
|
|
4074
4172
|
}
|
|
4075
4173
|
/** Delete the active thread if nothing was ever sent in it. */
|
|
4076
4174
|
reapUnsent() {
|
|
@@ -4156,43 +4254,76 @@ var ConversationHistory = class {
|
|
|
4156
4254
|
* Uses a short-lived agent pointed at the resume / fork endpoint and seeded
|
|
4157
4255
|
* with no history, because those endpoints supply the prior turns from the
|
|
4158
4256
|
* snapshot and re-sending them would duplicate. A separate agent makes that
|
|
4159
|
-
* structural
|
|
4160
|
-
* `run_id` the endpoints also require.
|
|
4257
|
+
* structural and mints the fresh `run_id` the endpoints also require.
|
|
4161
4258
|
*
|
|
4162
4259
|
* Built by the same construction as the conversation's own client, so the
|
|
4163
4260
|
* continuation streams into the same transcript the user is looking at and
|
|
4164
4261
|
* runs under the same state, tools and bounds. It is the run in flight while
|
|
4165
4262
|
* it lasts: {@link stopContinuation} is how the element's Stop reaches it.
|
|
4263
|
+
*
|
|
4264
|
+
* What it adds joins the conversation. Its saves write the conversation on
|
|
4265
|
+
* screen ahead of its exchange, and each one hands that whole list to the
|
|
4266
|
+
* next client the element builds, so the next ordinary message is sent with
|
|
4267
|
+
* the exchange it follows. The conversation's own client never held it, and
|
|
4268
|
+
* was sending without it.
|
|
4166
4269
|
*/
|
|
4167
4270
|
async continueRun(runId, verb) {
|
|
4168
4271
|
const index = this.runs();
|
|
4169
4272
|
if (index === null) {
|
|
4170
4273
|
return;
|
|
4171
4274
|
}
|
|
4275
|
+
if (this.#host.running() || this.#continuation !== null) {
|
|
4276
|
+
this.#refuse(this.#host.strings().continueWhileRunning);
|
|
4277
|
+
return;
|
|
4278
|
+
}
|
|
4172
4279
|
const content = this.#host.input.value.trim();
|
|
4173
4280
|
if (content === "") {
|
|
4174
|
-
this.#
|
|
4175
|
-
this.#host.hint.hidden = false;
|
|
4176
|
-
this.#host.input.focus();
|
|
4281
|
+
this.#refuse(this.#host.strings().continueNeedsTurn);
|
|
4177
4282
|
return;
|
|
4178
4283
|
}
|
|
4179
4284
|
this.#host.input.value = "";
|
|
4180
4285
|
this.#host.autoGrow();
|
|
4286
|
+
const cleared = this.#cleared;
|
|
4181
4287
|
const client = this.#host.buildClient({
|
|
4182
4288
|
endpoint: verb === "resume" ? index.resumeUrl(runId) : index.forkUrl(runId),
|
|
4183
4289
|
// The seed the endpoints assume: nothing. The snapshot is the history.
|
|
4184
4290
|
initialMessages: [],
|
|
4185
|
-
//
|
|
4186
|
-
//
|
|
4187
|
-
// client
|
|
4188
|
-
|
|
4291
|
+
// What its saves write ahead of the exchange: the conversation on screen,
|
|
4292
|
+
// in the form the store holds it. From the conversation's own client when
|
|
4293
|
+
// there is one, because that client keeps how each call ended beside its
|
|
4294
|
+
// messages rather than on them; otherwise what the last restore or
|
|
4295
|
+
// continuation wrote, which is already in that form.
|
|
4296
|
+
//
|
|
4297
|
+
// All of it, even where this forks an earlier run and the server's
|
|
4298
|
+
// snapshot stops there: what is saved is what the screen shows.
|
|
4299
|
+
follows: this.#host.client()?.messages ?? this.#restored,
|
|
4300
|
+
onSaved: (conversation) => {
|
|
4301
|
+
if (cleared !== this.#cleared) {
|
|
4302
|
+
return;
|
|
4303
|
+
}
|
|
4304
|
+
this.#restored = conversation;
|
|
4305
|
+
this.#host.releaseClient();
|
|
4306
|
+
}
|
|
4189
4307
|
});
|
|
4190
4308
|
this.#continuation = client;
|
|
4191
|
-
|
|
4192
|
-
|
|
4193
|
-
|
|
4309
|
+
try {
|
|
4310
|
+
await client.send(content);
|
|
4311
|
+
} finally {
|
|
4312
|
+
if (this.#continuation === client) {
|
|
4313
|
+
this.#continuation = null;
|
|
4314
|
+
this.#host.continuationEnded();
|
|
4315
|
+
}
|
|
4194
4316
|
}
|
|
4195
4317
|
}
|
|
4318
|
+
/**
|
|
4319
|
+
* Say at the composer why a picked run did not continue, and put the caret
|
|
4320
|
+
* there. The hint clears itself on the next keystroke.
|
|
4321
|
+
*/
|
|
4322
|
+
#refuse(reason) {
|
|
4323
|
+
this.#host.hint.textContent = reason;
|
|
4324
|
+
this.#host.hint.hidden = false;
|
|
4325
|
+
this.#host.input.focus();
|
|
4326
|
+
}
|
|
4196
4327
|
/**
|
|
4197
4328
|
* Restore the conversation from the store on mount, then — if a navigating
|
|
4198
4329
|
* tool reloaded the page mid-run — resume the loop by supplying that tool's
|
|
@@ -4244,14 +4375,13 @@ var ConversationHistory = class {
|
|
|
4244
4375
|
const restored = answerUnansweredCalls(
|
|
4245
4376
|
messages,
|
|
4246
4377
|
// The shape the store holds for a call the client answered the same way:
|
|
4247
|
-
// its tool message, with the outcome
|
|
4248
|
-
// Cast at the AG-UI boundary, as the client's own annotation is.
|
|
4378
|
+
// its tool message, with the outcome in its metadata.
|
|
4249
4379
|
(toolCallId) => ({
|
|
4250
4380
|
id: randomUUID3(),
|
|
4251
4381
|
role: "tool",
|
|
4252
4382
|
content: unfinished,
|
|
4253
4383
|
toolCallId,
|
|
4254
|
-
outcome: TOOL_OUTCOME.INTERRUPTED
|
|
4384
|
+
metadata: { outcome: TOOL_OUTCOME.INTERRUPTED }
|
|
4255
4385
|
}),
|
|
4256
4386
|
new Set(checkpoint === null ? [] : [checkpoint.toolCallId])
|
|
4257
4387
|
);
|
|
@@ -4343,8 +4473,10 @@ var ConversationHistory = class {
|
|
|
4343
4473
|
const card = this.#host.transcript.card(message.toolCallId);
|
|
4344
4474
|
if (card !== void 0) {
|
|
4345
4475
|
card.settle(
|
|
4346
|
-
toolStatusFromOutcome(message
|
|
4347
|
-
|
|
4476
|
+
toolStatusFromOutcome(metadataOrTopLevel(message, "outcome")),
|
|
4477
|
+
// Flattened exactly as the live path flattens it, so a reload shows
|
|
4478
|
+
// the card the user watched settle.
|
|
4479
|
+
contentToText(message.content)
|
|
4348
4480
|
);
|
|
4349
4481
|
}
|
|
4350
4482
|
}
|
|
@@ -4784,6 +4916,7 @@ var STEP = 16;
|
|
|
4784
4916
|
var COARSE_STEP = 64;
|
|
4785
4917
|
function enableLauncherDrag(launcher, options) {
|
|
4786
4918
|
let suppressClick = false;
|
|
4919
|
+
const { signal } = options;
|
|
4787
4920
|
launcher.addEventListener(
|
|
4788
4921
|
"click",
|
|
4789
4922
|
(event) => {
|
|
@@ -4794,54 +4927,58 @@ function enableLauncherDrag(launcher, options) {
|
|
|
4794
4927
|
event.stopPropagation();
|
|
4795
4928
|
event.preventDefault();
|
|
4796
4929
|
},
|
|
4797
|
-
true
|
|
4930
|
+
{ capture: true, signal }
|
|
4798
4931
|
);
|
|
4799
|
-
launcher.addEventListener(
|
|
4800
|
-
|
|
4801
|
-
|
|
4802
|
-
|
|
4803
|
-
|
|
4804
|
-
const start = options.rect();
|
|
4805
|
-
const originX = event.clientX;
|
|
4806
|
-
const originY = event.clientY;
|
|
4807
|
-
let dragging = false;
|
|
4808
|
-
const onMove = (move) => {
|
|
4809
|
-
const dx = move.clientX - originX;
|
|
4810
|
-
const dy = move.clientY - originY;
|
|
4811
|
-
if (!dragging && Math.hypot(dx, dy) < DRAG_THRESHOLD) {
|
|
4812
|
-
return;
|
|
4813
|
-
}
|
|
4814
|
-
dragging = true;
|
|
4815
|
-
launcher.setAttribute("data-dragging", "true");
|
|
4816
|
-
const next = clampLauncher(
|
|
4817
|
-
{ ...start, left: start.left + dx, top: start.top + dy },
|
|
4818
|
-
options.viewport()
|
|
4819
|
-
);
|
|
4820
|
-
options.apply(next.left, next.top);
|
|
4821
|
-
};
|
|
4822
|
-
const onUp = (up) => {
|
|
4823
|
-
window.removeEventListener("pointermove", onMove);
|
|
4824
|
-
window.removeEventListener("pointerup", onUp);
|
|
4825
|
-
window.removeEventListener("pointercancel", onUp);
|
|
4826
|
-
if (!dragging) {
|
|
4932
|
+
launcher.addEventListener(
|
|
4933
|
+
"pointerdown",
|
|
4934
|
+
(event) => {
|
|
4935
|
+
suppressClick = false;
|
|
4936
|
+
if (!options.enabled()) {
|
|
4827
4937
|
return;
|
|
4828
4938
|
}
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
const
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4835
|
-
|
|
4836
|
-
|
|
4837
|
-
|
|
4838
|
-
|
|
4839
|
-
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
|
|
4844
|
-
|
|
4939
|
+
const start = options.rect();
|
|
4940
|
+
const originX = event.clientX;
|
|
4941
|
+
const originY = event.clientY;
|
|
4942
|
+
let dragging = false;
|
|
4943
|
+
const onMove = (move) => {
|
|
4944
|
+
const dx = move.clientX - originX;
|
|
4945
|
+
const dy = move.clientY - originY;
|
|
4946
|
+
if (!dragging && Math.hypot(dx, dy) < DRAG_THRESHOLD) {
|
|
4947
|
+
return;
|
|
4948
|
+
}
|
|
4949
|
+
dragging = true;
|
|
4950
|
+
launcher.setAttribute("data-dragging", "true");
|
|
4951
|
+
const next = clampLauncher(
|
|
4952
|
+
{ ...start, left: start.left + dx, top: start.top + dy },
|
|
4953
|
+
options.viewport()
|
|
4954
|
+
);
|
|
4955
|
+
options.apply(next.left, next.top);
|
|
4956
|
+
};
|
|
4957
|
+
const onUp = (up) => {
|
|
4958
|
+
window.removeEventListener("pointermove", onMove);
|
|
4959
|
+
window.removeEventListener("pointerup", onUp);
|
|
4960
|
+
window.removeEventListener("pointercancel", onUp);
|
|
4961
|
+
if (!dragging) {
|
|
4962
|
+
return;
|
|
4963
|
+
}
|
|
4964
|
+
launcher.removeAttribute("data-dragging");
|
|
4965
|
+
suppressClick = true;
|
|
4966
|
+
const next = clampLauncher(
|
|
4967
|
+
{
|
|
4968
|
+
...start,
|
|
4969
|
+
left: start.left + (up.clientX - originX),
|
|
4970
|
+
top: start.top + (up.clientY - originY)
|
|
4971
|
+
},
|
|
4972
|
+
options.viewport()
|
|
4973
|
+
);
|
|
4974
|
+
options.commit(next.left, next.top);
|
|
4975
|
+
};
|
|
4976
|
+
window.addEventListener("pointermove", onMove);
|
|
4977
|
+
window.addEventListener("pointerup", onUp);
|
|
4978
|
+
window.addEventListener("pointercancel", onUp);
|
|
4979
|
+
},
|
|
4980
|
+
{ signal }
|
|
4981
|
+
);
|
|
4845
4982
|
let pending = null;
|
|
4846
4983
|
const settle = () => {
|
|
4847
4984
|
if (pending === null) {
|
|
@@ -4851,32 +4988,36 @@ function enableLauncherDrag(launcher, options) {
|
|
|
4851
4988
|
pending = null;
|
|
4852
4989
|
options.commit(left, top);
|
|
4853
4990
|
};
|
|
4854
|
-
launcher.addEventListener(
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
|
|
4858
|
-
|
|
4859
|
-
|
|
4860
|
-
|
|
4861
|
-
|
|
4862
|
-
moved =
|
|
4863
|
-
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4872
|
-
|
|
4873
|
-
|
|
4874
|
-
|
|
4875
|
-
|
|
4876
|
-
|
|
4877
|
-
|
|
4878
|
-
|
|
4879
|
-
|
|
4991
|
+
launcher.addEventListener(
|
|
4992
|
+
"keydown",
|
|
4993
|
+
(event) => {
|
|
4994
|
+
if (!options.enabled()) {
|
|
4995
|
+
return;
|
|
4996
|
+
}
|
|
4997
|
+
const step = event.shiftKey ? COARSE_STEP : STEP;
|
|
4998
|
+
const rect = options.rect();
|
|
4999
|
+
let moved = null;
|
|
5000
|
+
if (event.key === "ArrowLeft") {
|
|
5001
|
+
moved = { left: rect.left - step, top: rect.top };
|
|
5002
|
+
} else if (event.key === "ArrowRight") {
|
|
5003
|
+
moved = { left: rect.left + step, top: rect.top };
|
|
5004
|
+
} else if (event.key === "ArrowUp") {
|
|
5005
|
+
moved = { left: rect.left, top: rect.top - step };
|
|
5006
|
+
} else if (event.key === "ArrowDown") {
|
|
5007
|
+
moved = { left: rect.left, top: rect.top + step };
|
|
5008
|
+
}
|
|
5009
|
+
if (moved === null) {
|
|
5010
|
+
return;
|
|
5011
|
+
}
|
|
5012
|
+
event.preventDefault();
|
|
5013
|
+
const next = clampLauncher({ ...rect, ...moved }, options.viewport());
|
|
5014
|
+
options.apply(next.left, next.top);
|
|
5015
|
+
pending = next;
|
|
5016
|
+
},
|
|
5017
|
+
{ signal }
|
|
5018
|
+
);
|
|
5019
|
+
launcher.addEventListener("keyup", settle, { signal });
|
|
5020
|
+
launcher.addEventListener("blur", settle, { signal });
|
|
4880
5021
|
}
|
|
4881
5022
|
|
|
4882
5023
|
// src/ui/placement/place_widget.ts
|
|
@@ -5123,8 +5264,9 @@ var PanelPlacement = class {
|
|
|
5123
5264
|
* away and unclickable behind the open panel, so a drag there would move
|
|
5124
5265
|
* something nobody can see.
|
|
5125
5266
|
*/
|
|
5126
|
-
enableLauncherDrag() {
|
|
5267
|
+
enableLauncherDrag(signal) {
|
|
5127
5268
|
enableLauncherDrag(this.#host.launcher, {
|
|
5269
|
+
signal,
|
|
5128
5270
|
enabled: () => this.#host.collapsed() && this.#launcherDraggable(),
|
|
5129
5271
|
rect: () => this.#launcherBox(),
|
|
5130
5272
|
viewport: () => this.#viewport(),
|
|
@@ -5509,20 +5651,26 @@ var PanelPlacement = class {
|
|
|
5509
5651
|
if (visual === null || visual === void 0) {
|
|
5510
5652
|
return;
|
|
5511
5653
|
}
|
|
5512
|
-
|
|
5654
|
+
const layout = this.#screen().height;
|
|
5655
|
+
if (Math.abs(visual.height - layout) < 1) {
|
|
5513
5656
|
this.#host.element.style.removeProperty("--ag-ui-visual-viewport-height");
|
|
5514
5657
|
this.#host.element.style.removeProperty("--ag-ui-visual-viewport-inset-bottom");
|
|
5658
|
+
this.#host.element.style.removeProperty("--ag-ui-visual-viewport-inset-top");
|
|
5515
5659
|
return;
|
|
5516
5660
|
}
|
|
5517
5661
|
this.#host.element.style.setProperty(
|
|
5518
5662
|
"--ag-ui-visual-viewport-height",
|
|
5519
5663
|
`${Math.round(visual.height)}px`
|
|
5520
5664
|
);
|
|
5521
|
-
const hidden =
|
|
5665
|
+
const hidden = layout - visual.height - visual.offsetTop;
|
|
5522
5666
|
this.#host.element.style.setProperty(
|
|
5523
5667
|
"--ag-ui-visual-viewport-inset-bottom",
|
|
5524
5668
|
`${Math.max(0, Math.round(hidden))}px`
|
|
5525
5669
|
);
|
|
5670
|
+
this.#host.element.style.setProperty(
|
|
5671
|
+
"--ag-ui-visual-viewport-inset-top",
|
|
5672
|
+
`${Math.max(0, Math.round(visual.offsetTop))}px`
|
|
5673
|
+
);
|
|
5526
5674
|
}
|
|
5527
5675
|
/**
|
|
5528
5676
|
* The launcher's box in viewport coordinates, with its transform divided out.
|
|
@@ -6665,7 +6813,24 @@ var STYLES = `
|
|
|
6665
6813
|
keyboard changes no viewport-percentage length -- not vh, not dvh, not svh
|
|
6666
6814
|
-- so a full-bleed panel on a phone has to be told the height rather than
|
|
6667
6815
|
deriving it. The value to publish there is the visual viewport's. */
|
|
6668
|
-
--_viewport-height: var(
|
|
6816
|
+
--_viewport-height: var(
|
|
6817
|
+
--ag-ui-viewport-height,
|
|
6818
|
+
calc(
|
|
6819
|
+
min(var(--_visual-viewport-inset-top) + var(--_visual-viewport-height), 100dvh - var(--_viewport-inset-bottom)) -
|
|
6820
|
+
var(--_viewport-inset-top) - var(--_keyboard-inset-top)
|
|
6821
|
+
)
|
|
6822
|
+
);
|
|
6823
|
+
/* That default is the host's box cut to the part of the screen the user can
|
|
6824
|
+
see: from the top the panel starts at, the host's reserved top moved down
|
|
6825
|
+
by the keyboard inset below, to whichever is further up, the bottom of the
|
|
6826
|
+
visible area or the host's reserved bottom. Where nothing has measured, the
|
|
6827
|
+
visible area is the layout viewport with no pan, and this is the host's
|
|
6828
|
+
box exactly.
|
|
6829
|
+
|
|
6830
|
+
Cut rather than replaced. A measured height used as the whole answer kept
|
|
6831
|
+
a bar the host reserved at the top in the position and out of the height,
|
|
6832
|
+
so the panel ran that far past the bottom of the visible area, with its
|
|
6833
|
+
composer behind the keyboard. */
|
|
6669
6834
|
/* The measured height of the part of the screen the user can actually see,
|
|
6670
6835
|
written by the element from the visual viewport and falling back to the
|
|
6671
6836
|
layout viewport where nothing has measured yet.
|
|
@@ -6678,11 +6843,15 @@ var STYLES = `
|
|
|
6678
6843
|
|
|
6679
6844
|
Separate from the token above so a host that states the usable height
|
|
6680
6845
|
outright still wins: the element writes this one inline, and an inline
|
|
6681
|
-
value would otherwise outrank the host's own rule.
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6846
|
+
value would otherwise outrank the host's own rule.
|
|
6847
|
+
|
|
6848
|
+
The fallback is dvh rather than vh because the browser's own bars do move
|
|
6849
|
+
it, where a keyboard does not. iOS Safari resolves vh to the viewport with
|
|
6850
|
+
its bars collapsed, so on a page that does not scroll them away a panel
|
|
6851
|
+
sized from it ran under the address bar by the bars' height -- 40px on
|
|
6852
|
+
the phone measured -- with a docked composer underneath. dvh is the
|
|
6853
|
+
viewport with the bars as they are. */
|
|
6854
|
+
--_visual-viewport-height: var(--ag-ui-visual-viewport-height, 100dvh);
|
|
6686
6855
|
/* How much of the layout viewport is hidden below the visible one, measured
|
|
6687
6856
|
and written by the element alongside the height above.
|
|
6688
6857
|
|
|
@@ -6697,6 +6866,24 @@ var STYLES = `
|
|
|
6697
6866
|
A host wanting no keyboard lift at all sets --ag-ui-keyboard-inset: 0px. */
|
|
6698
6867
|
--_keyboard-inset: var(--ag-ui-keyboard-inset, var(--_visual-viewport-inset-bottom));
|
|
6699
6868
|
--_visual-viewport-inset-bottom: var(--ag-ui-visual-viewport-inset-bottom, 0px);
|
|
6869
|
+
/* How far a panel anchored at the top moves down for a keyboard, below the
|
|
6870
|
+
top the host reserved. With the same two-token shape as the lift above;
|
|
6871
|
+
0px keeps the panel at the host's top.
|
|
6872
|
+
|
|
6873
|
+
To show the field being typed into, a browser pans the visible area down
|
|
6874
|
+
the layout viewport, and a fixed element stays against the layout top, so
|
|
6875
|
+
a panel that did not move showed only its lower part, from the pan down,
|
|
6876
|
+
with its header off the screen and an empty band under it. It moves by
|
|
6877
|
+
what the pan goes past the host's reserved top, not by the whole pan: the
|
|
6878
|
+
pan scrolls a bar reserved there away with the rest of the page rather
|
|
6879
|
+
than pushing it down, and adding the two put the panel a whole bar below
|
|
6880
|
+
the visible area. A corner panel anchored at the bottom does not use this,
|
|
6881
|
+
because the band below already accounts for the pan. */
|
|
6882
|
+
--_keyboard-inset-top: var(--ag-ui-keyboard-inset-top, max(0px, var(--_visual-viewport-inset-top) - var(--_viewport-inset-top)));
|
|
6883
|
+
/* How much of the layout viewport is hidden above the visible one: how far
|
|
6884
|
+
the browser panned. Measured and written by the element with the two
|
|
6885
|
+
above. */
|
|
6886
|
+
--_visual-viewport-inset-top: var(--ag-ui-visual-viewport-inset-top, 0px);
|
|
6700
6887
|
--_viewport-width: var(
|
|
6701
6888
|
--ag-ui-viewport-width,
|
|
6702
6889
|
calc(100vw - var(--_viewport-inset-left) - var(--_viewport-inset-right))
|
|
@@ -6833,7 +7020,7 @@ var STYLES = `
|
|
|
6833
7020
|
}
|
|
6834
7021
|
|
|
6835
7022
|
:host([placement="side"]) {
|
|
6836
|
-
--_inset: var(--ag-ui-inset, var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
|
|
7023
|
+
--_inset: var(--ag-ui-inset, calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
|
|
6837
7024
|
--_width: var(--ag-ui-width, 420px);
|
|
6838
7025
|
--_height: var(--ag-ui-height, var(--_viewport-height));
|
|
6839
7026
|
--_max-height: var(--ag-ui-max-height, var(--_viewport-height));
|
|
@@ -6843,7 +7030,8 @@ var STYLES = `
|
|
|
6843
7030
|
:host([placement="full"]) {
|
|
6844
7031
|
--_inset: var(
|
|
6845
7032
|
--ag-ui-inset,
|
|
6846
|
-
var(--_viewport-inset-top)
|
|
7033
|
+
calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
|
|
7034
|
+
var(--_viewport-inset-bottom) var(--_viewport-inset-left)
|
|
6847
7035
|
);
|
|
6848
7036
|
--_width: var(--ag-ui-width, var(--_viewport-width));
|
|
6849
7037
|
--_height: var(--ag-ui-height, var(--_viewport-height));
|
|
@@ -6860,7 +7048,8 @@ var STYLES = `
|
|
|
6860
7048
|
:host([placement="page"]) {
|
|
6861
7049
|
--_inset: var(
|
|
6862
7050
|
--ag-ui-inset,
|
|
6863
|
-
var(--_viewport-inset-top)
|
|
7051
|
+
calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
|
|
7052
|
+
var(--_viewport-inset-bottom) var(--_viewport-inset-left)
|
|
6864
7053
|
);
|
|
6865
7054
|
--_width: var(--ag-ui-width, var(--_viewport-width));
|
|
6866
7055
|
--_height: var(--ag-ui-height, var(--_viewport-height));
|
|
@@ -6926,7 +7115,7 @@ var STYLES = `
|
|
|
6926
7115
|
:host([placement=""]:not([data-small-viewport="off"])) {
|
|
6927
7116
|
--_inset: var(
|
|
6928
7117
|
--ag-ui-inset,
|
|
6929
|
-
var(--_viewport-inset-top) var(--_viewport-inset-right)
|
|
7118
|
+
calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right)
|
|
6930
7119
|
calc(var(--_viewport-inset-bottom) + var(--_keyboard-inset))
|
|
6931
7120
|
var(--_viewport-inset-left)
|
|
6932
7121
|
);
|
|
@@ -6956,7 +7145,7 @@ var STYLES = `
|
|
|
6956
7145
|
--ag-ui-position: static (and place this element in your own layout) for a
|
|
6957
7146
|
host-managed push instead. */
|
|
6958
7147
|
:host([placement="sidebar"]) {
|
|
6959
|
-
--_inset: var(--ag-ui-inset, var(--_viewport-inset-top) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
|
|
7148
|
+
--_inset: var(--ag-ui-inset, calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) var(--_viewport-inset-right) var(--_viewport-inset-bottom) auto);
|
|
6960
7149
|
--_width: var(--ag-ui-width, 420px);
|
|
6961
7150
|
--_height: var(--ag-ui-height, var(--_viewport-height));
|
|
6962
7151
|
--_max-height: var(--ag-ui-max-height, var(--_viewport-height));
|
|
@@ -6965,7 +7154,11 @@ var STYLES = `
|
|
|
6965
7154
|
}
|
|
6966
7155
|
|
|
6967
7156
|
:host([placement="sidebar"][data-side="left"]) {
|
|
6968
|
-
--_inset: var(
|
|
7157
|
+
--_inset: var(
|
|
7158
|
+
--ag-ui-inset,
|
|
7159
|
+
calc(var(--_viewport-inset-top) + var(--_keyboard-inset-top)) auto var(--_viewport-inset-bottom)
|
|
7160
|
+
var(--_viewport-inset-left)
|
|
7161
|
+
);
|
|
6969
7162
|
}
|
|
6970
7163
|
|
|
6971
7164
|
/* The docked panel is pinned to the edge it docks against rather than filling
|
|
@@ -7722,6 +7915,64 @@ var STYLES = `
|
|
|
7722
7915
|
border-block-start-color: transparent;
|
|
7723
7916
|
}
|
|
7724
7917
|
|
|
7918
|
+
/* On a phone the composer stays at the foot and the greeting takes the room
|
|
7919
|
+
above it, which is the other way round from everything above.
|
|
7920
|
+
|
|
7921
|
+
Centring is a shape for a screen with room to spare: the composer reads as
|
|
7922
|
+
the one thing on the page, and whichever way the rows grow there is space
|
|
7923
|
+
left on both sides of them. A phone has no space to spare, and the keyboard
|
|
7924
|
+
is what takes it -- opening one leaves a 426px-tall visible area with the
|
|
7925
|
+
composer halfway up it and an empty band underneath, which is the half of
|
|
7926
|
+
the screen a thumb is already resting on. Docked, the field sits directly
|
|
7927
|
+
over the keyboard, where every chat on the platform puts it, and the
|
|
7928
|
+
greeting keeps the rest.
|
|
7929
|
+
|
|
7930
|
+
Both rules restate the selector they override, with the breakpoint's own
|
|
7931
|
+
opt-out added: this is part of the shape a host keeps its desktop layout
|
|
7932
|
+
instead of, so it goes the same way as the rest of that shape. Restating
|
|
7933
|
+
rather than adding conditions to the originals keeps each of those rules
|
|
7934
|
+
readable as one decision, and source order settles the pair. */
|
|
7935
|
+
@media (max-width: 600px) {
|
|
7936
|
+
:host([data-empty]:not([data-restoring]):not([data-small-viewport="off"])) .chat::after {
|
|
7937
|
+
flex-grow: 0;
|
|
7938
|
+
}
|
|
7939
|
+
|
|
7940
|
+
/* The empty region fills the transcript instead of being centred in it as a
|
|
7941
|
+
block, so the two things in it can go to different places: the prompts the
|
|
7942
|
+
host offers to the foot, against the composer, and the greeting to the
|
|
7943
|
+
middle of what they leave.
|
|
7944
|
+
|
|
7945
|
+
A prompt chip is a way into the conversation. Against the field it starts,
|
|
7946
|
+
it reads as one; under the greeting halfway up the panel, with the field
|
|
7947
|
+
at the foot, it reads as decoration next to something else. Nothing here
|
|
7948
|
+
moves them on a screen where the composer is still centred: there the
|
|
7949
|
+
whole region hangs at the foot of the upper half, directly over the
|
|
7950
|
+
composer, and the prompts are already against it.
|
|
7951
|
+
|
|
7952
|
+
Auto block margins on the greeting are what centre it, and they take the
|
|
7953
|
+
free space whether or not there are prompts below to leave any, so a host
|
|
7954
|
+
that offers none gets a greeting in the middle of the transcript rather
|
|
7955
|
+
than one clinging to the composer.
|
|
7956
|
+
The region declares a display here, which outranks the rule collapsing a
|
|
7957
|
+
hidden one, so it says it is not hidden itself. Nothing sets the two
|
|
7958
|
+
apart today -- the transcript writes the hidden property and the host's
|
|
7959
|
+
data-empty from one expression -- and that is exactly why: a rule holding
|
|
7960
|
+
because of how a method in another file happens to be written is a rule
|
|
7961
|
+
holding by luck. */
|
|
7962
|
+
:host([placement="page"][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .empty:not([hidden]),
|
|
7963
|
+
:host([placement="embedded"][data-greeting][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .empty:not([hidden]) {
|
|
7964
|
+
margin: 0;
|
|
7965
|
+
flex: 1;
|
|
7966
|
+
display: flex;
|
|
7967
|
+
flex-direction: column;
|
|
7968
|
+
}
|
|
7969
|
+
|
|
7970
|
+
:host([placement="page"][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .greeting,
|
|
7971
|
+
:host([placement="embedded"][data-greeting][data-empty]:not([data-greeting="off"]):not([data-restoring]):not([data-small-viewport="off"])) .greeting {
|
|
7972
|
+
margin-block: auto;
|
|
7973
|
+
}
|
|
7974
|
+
}
|
|
7975
|
+
|
|
7725
7976
|
/* Nor does the greeting paint while a restore is in flight. Hidden rather than
|
|
7726
7977
|
removed, so it keeps its place and nothing around it moves when it shows. */
|
|
7727
7978
|
:host([data-restoring]) .greeting {
|
|
@@ -8205,6 +8456,17 @@ var STYLES = `
|
|
|
8205
8456
|
gap: 3px;
|
|
8206
8457
|
}
|
|
8207
8458
|
|
|
8459
|
+
/* A call with no arguments drops the region rather than framing an empty
|
|
8460
|
+
object, and a settled card drops the result region until it has one -- both
|
|
8461
|
+
by setting the hidden property, and an author display beats the user-agent
|
|
8462
|
+
rule for that attribute. Without this the region kept laying out: 42px of
|
|
8463
|
+
card holding the ARGUMENTS heading over nothing, on every call the agent
|
|
8464
|
+
made with no arguments, in the display mode that shows arguments by
|
|
8465
|
+
default. */
|
|
8466
|
+
.tool-call-section[hidden] {
|
|
8467
|
+
display: none;
|
|
8468
|
+
}
|
|
8469
|
+
|
|
8208
8470
|
/* The heading that tells the two payloads apart. Without it the arguments and
|
|
8209
8471
|
the result were one run of text and a reader had to guess the boundary. */
|
|
8210
8472
|
.tool-call-section-label {
|
|
@@ -8875,8 +9137,8 @@ var STYLES = `
|
|
|
8875
9137
|
display: none;
|
|
8876
9138
|
}
|
|
8877
9139
|
|
|
8878
|
-
/* The mic button's mount point; filled only once
|
|
8879
|
-
control. */
|
|
9140
|
+
/* The mic button's mount point; filled only once ComposerVoice.wire mounts
|
|
9141
|
+
the control, which it skips unless transcription is configured. */
|
|
8880
9142
|
.voice-slot {
|
|
8881
9143
|
display: contents;
|
|
8882
9144
|
}
|
|
@@ -9553,6 +9815,15 @@ var STYLES = `
|
|
|
9553
9815
|
padding: 10px 12px;
|
|
9554
9816
|
}
|
|
9555
9817
|
|
|
9818
|
+
/* The row is hidden whenever the host offers no skills, which is most elements
|
|
9819
|
+
most of the time, and an author display beats the user-agent rule for the
|
|
9820
|
+
hidden attribute. Without this it kept its padding: 20px of panel between
|
|
9821
|
+
the transcript and the composer, under every placement, reading as the gap
|
|
9822
|
+
under whatever the transcript ends with. */
|
|
9823
|
+
.skill-chips[hidden] {
|
|
9824
|
+
display: none;
|
|
9825
|
+
}
|
|
9826
|
+
|
|
9556
9827
|
.skill-chip {
|
|
9557
9828
|
border: 1px solid var(--_border);
|
|
9558
9829
|
border-radius: 999px;
|
|
@@ -10505,7 +10776,7 @@ var AnswerActions = class {
|
|
|
10505
10776
|
}
|
|
10506
10777
|
};
|
|
10507
10778
|
|
|
10508
|
-
// node_modules/.pnpm/dompurify@3.4.
|
|
10779
|
+
// node_modules/.pnpm/dompurify@3.4.15/node_modules/dompurify/dist/purify.es.mjs
|
|
10509
10780
|
function _arrayLikeToArray(r, a) {
|
|
10510
10781
|
(null == a || a > r.length) && (a = r.length);
|
|
10511
10782
|
for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
|
|
@@ -10514,18 +10785,18 @@ function _arrayLikeToArray(r, a) {
|
|
|
10514
10785
|
function _arrayWithHoles(r) {
|
|
10515
10786
|
if (Array.isArray(r)) return r;
|
|
10516
10787
|
}
|
|
10517
|
-
function _iterableToArrayLimit(r,
|
|
10788
|
+
function _iterableToArrayLimit(r, l) {
|
|
10518
10789
|
var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"];
|
|
10519
10790
|
if (null != t) {
|
|
10520
|
-
var e, n, i,
|
|
10791
|
+
var e, n, i, u3, a = [], f2 = true, o = false;
|
|
10521
10792
|
try {
|
|
10522
|
-
if (i = (t = t.call(r)).next, 0 ===
|
|
10523
|
-
else for (; !(f2 = (e = i.call(t)).done) && (a.push(e.value), a.length !==
|
|
10793
|
+
if (i = (t = t.call(r)).next, 0 === l) ;
|
|
10794
|
+
else for (; !(f2 = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f2 = true) ;
|
|
10524
10795
|
} catch (r2) {
|
|
10525
10796
|
o = true, n = r2;
|
|
10526
10797
|
} finally {
|
|
10527
10798
|
try {
|
|
10528
|
-
if (!f2 && null != t.return && (
|
|
10799
|
+
if (!f2 && null != t.return && (u3 = t.return(), Object(u3) !== u3)) return;
|
|
10529
10800
|
} finally {
|
|
10530
10801
|
if (o) throw n;
|
|
10531
10802
|
}
|
|
@@ -10630,14 +10901,14 @@ function addToSet(set, array) {
|
|
|
10630
10901
|
if (!arrayIsArray(array)) {
|
|
10631
10902
|
return set;
|
|
10632
10903
|
}
|
|
10633
|
-
let
|
|
10634
|
-
while (
|
|
10635
|
-
let element = array[
|
|
10904
|
+
let l = array.length;
|
|
10905
|
+
while (l--) {
|
|
10906
|
+
let element = array[l];
|
|
10636
10907
|
if (typeof element === "string") {
|
|
10637
10908
|
const lcElement = transformCaseFunc(element);
|
|
10638
10909
|
if (lcElement !== element) {
|
|
10639
10910
|
if (!isFrozen(array)) {
|
|
10640
|
-
array[
|
|
10911
|
+
array[l] = lcElement;
|
|
10641
10912
|
}
|
|
10642
10913
|
element = lcElement;
|
|
10643
10914
|
}
|
|
@@ -10845,7 +11116,7 @@ var _resolveObjectOption = function _resolveObjectOption2(cfg, key, makeFallback
|
|
|
10845
11116
|
function createDOMPurify() {
|
|
10846
11117
|
let window2 = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : getGlobal();
|
|
10847
11118
|
const DOMPurify = (root) => createDOMPurify(root);
|
|
10848
|
-
DOMPurify.version = "3.4.
|
|
11119
|
+
DOMPurify.version = "3.4.15";
|
|
10849
11120
|
DOMPurify.removed = [];
|
|
10850
11121
|
if (!window2 || !window2.document || window2.document.nodeType !== NODE_TYPE.document || !window2.Element) {
|
|
10851
11122
|
DOMPurify.isSupported = false;
|
|
@@ -10862,6 +11133,7 @@ function createDOMPurify() {
|
|
|
10862
11133
|
const ElementPrototype = Element2.prototype;
|
|
10863
11134
|
const cloneNode = lookupGetter(ElementPrototype, "cloneNode");
|
|
10864
11135
|
const remove = lookupGetter(ElementPrototype, "remove");
|
|
11136
|
+
const removeAttributeNode = lookupGetter(ElementPrototype, "removeAttributeNode");
|
|
10865
11137
|
const getNextSibling = lookupGetter(ElementPrototype, "nextSibling");
|
|
10866
11138
|
const getChildNodes = lookupGetter(ElementPrototype, "childNodes");
|
|
10867
11139
|
const getParentNode = lookupGetter(ElementPrototype, "parentNode");
|
|
@@ -11295,7 +11567,7 @@ function createDOMPurify() {
|
|
|
11295
11567
|
};
|
|
11296
11568
|
const _stripAttributeNode = function _stripAttributeNode2(element, attribute, name) {
|
|
11297
11569
|
try {
|
|
11298
|
-
|
|
11570
|
+
removeAttributeNode(element, attribute);
|
|
11299
11571
|
} catch (_2) {
|
|
11300
11572
|
try {
|
|
11301
11573
|
element.removeAttribute(name);
|
|
@@ -11343,7 +11615,7 @@ function createDOMPurify() {
|
|
|
11343
11615
|
});
|
|
11344
11616
|
try {
|
|
11345
11617
|
if (attr) {
|
|
11346
|
-
|
|
11618
|
+
removeAttributeNode(element, attr);
|
|
11347
11619
|
} else {
|
|
11348
11620
|
element.removeAttribute(name);
|
|
11349
11621
|
}
|
|
@@ -11531,7 +11803,16 @@ function createDOMPurify() {
|
|
|
11531
11803
|
// makes the direct read diverge from the cached read; a clean form
|
|
11532
11804
|
// (same-realm OR foreign-realm) has both reads pointing at the same
|
|
11533
11805
|
// canonical NamedNodeMap.
|
|
11534
|
-
element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" ||
|
|
11806
|
+
element.attributes !== getAttributes(element) || typeof element.removeAttribute !== "function" || // A form descendant named "removeAttributeNode" or "getAttributeNode"
|
|
11807
|
+
// shadows these Attr-node methods via [LegacyOverrideBuiltIns].
|
|
11808
|
+
// _removeAttribute() / _stripAttributeNode() reach for
|
|
11809
|
+
// element.removeAttributeNode(attr) first; when it is shadowed the call
|
|
11810
|
+
// throws and the name-based fallback element.removeAttribute(name)
|
|
11811
|
+
// ASCII-lowercases its lookup key in an HTML document, silently missing
|
|
11812
|
+
// a case-preserved event-handler attribute (e.g. an ONANIMATIONSTART
|
|
11813
|
+
// that reached the sanitizer through an XML/XHTML parse). Flag the form
|
|
11814
|
+
// so it is removed wholesale, exactly as for the other shadowed methods.
|
|
11815
|
+
typeof element.removeAttributeNode !== "function" || typeof element.getAttributeNode !== "function" || typeof element.setAttribute !== "function" || typeof element.namespaceURI !== "string" || typeof element.insertBefore !== "function" || typeof element.hasChildNodes !== "function" || // NodeType clobbering probe. Cached Node.prototype.nodeType getter
|
|
11535
11816
|
// returns the integer 1 for any Element regardless of realm; direct
|
|
11536
11817
|
// read on a clobbered form (e.g. <input name="nodeType">) returns
|
|
11537
11818
|
// the named child element. Cheap addition — nodeType is read from
|
|
@@ -11757,11 +12038,12 @@ function createDOMPurify() {
|
|
|
11757
12038
|
}
|
|
11758
12039
|
if (_isClobbered(currentNode)) {
|
|
11759
12040
|
_forceRemove(currentNode);
|
|
11760
|
-
|
|
11761
|
-
arrayPop(DOMPurify.removed);
|
|
12041
|
+
return false;
|
|
11762
12042
|
}
|
|
12043
|
+
return true;
|
|
11763
12044
|
} catch (_2) {
|
|
11764
12045
|
_removeAttribute(name, currentNode);
|
|
12046
|
+
return false;
|
|
11765
12047
|
}
|
|
11766
12048
|
};
|
|
11767
12049
|
const _sanitizeAttributes = function _sanitizeAttributes2(currentNode) {
|
|
@@ -11778,14 +12060,15 @@ function createDOMPurify() {
|
|
|
11778
12060
|
allowedAttributes: ALLOWED_ATTR2,
|
|
11779
12061
|
forceKeepAttr: void 0
|
|
11780
12062
|
};
|
|
11781
|
-
let
|
|
12063
|
+
let l = attributes.length;
|
|
11782
12064
|
const lcTag = transformCaseFunc(currentNode.nodeName);
|
|
11783
|
-
while (
|
|
11784
|
-
const attr = attributes[
|
|
12065
|
+
while (l--) {
|
|
12066
|
+
const attr = attributes[l];
|
|
11785
12067
|
const name = attr.name, namespaceURI = attr.namespaceURI, attrValue = attr.value;
|
|
11786
12068
|
const lcName = transformCaseFunc(name);
|
|
11787
12069
|
const initValue = attrValue;
|
|
11788
12070
|
let value = name === "value" ? initValue : stringTrim(initValue);
|
|
12071
|
+
let recreatedNamedProp = false;
|
|
11789
12072
|
hookEvent.attrName = lcName;
|
|
11790
12073
|
hookEvent.attrValue = value;
|
|
11791
12074
|
hookEvent.keepAttr = true;
|
|
@@ -11795,6 +12078,7 @@ function createDOMPurify() {
|
|
|
11795
12078
|
if (SANITIZE_NAMED_PROPS && (lcName === "id" || lcName === "name") && stringIndexOf(value, SANITIZE_NAMED_PROPS_PREFIX) !== 0) {
|
|
11796
12079
|
_removeAttribute(name, currentNode, attr);
|
|
11797
12080
|
value = SANITIZE_NAMED_PROPS_PREFIX + value;
|
|
12081
|
+
recreatedNamedProp = true;
|
|
11798
12082
|
}
|
|
11799
12083
|
if (SAFE_FOR_XML && regExpTest(/((--!?|])>)|<\/(style|script|title|xmp|textarea|noscript|iframe|noembed|noframes)/i, value)) {
|
|
11800
12084
|
_removeAttribute(name, currentNode, attr);
|
|
@@ -11824,7 +12108,10 @@ function createDOMPurify() {
|
|
|
11824
12108
|
}
|
|
11825
12109
|
value = _applyTrustedTypesToAttribute(lcTag, lcName, namespaceURI, value);
|
|
11826
12110
|
if (value !== initValue) {
|
|
11827
|
-
_setAttributeValue(currentNode, name, namespaceURI, value);
|
|
12111
|
+
const cleanWrite = _setAttributeValue(currentNode, name, namespaceURI, value);
|
|
12112
|
+
if (cleanWrite && recreatedNamedProp) {
|
|
12113
|
+
arrayPop(DOMPurify.removed);
|
|
12114
|
+
}
|
|
11828
12115
|
}
|
|
11829
12116
|
}
|
|
11830
12117
|
_executeHooks(hooks.afterSanitizeAttributes, currentNode, null);
|
|
@@ -11934,9 +12221,9 @@ function createDOMPurify() {
|
|
|
11934
12221
|
const inPlace = IN_PLACE && typeof dirty !== "string" && _isNode(dirty);
|
|
11935
12222
|
if (inPlace) {
|
|
11936
12223
|
_neutralizePatchLinkage(dirty);
|
|
11937
|
-
const
|
|
11938
|
-
if (typeof
|
|
11939
|
-
const tagName = transformCaseFunc(
|
|
12224
|
+
const nn = _readNodeName(dirty);
|
|
12225
|
+
if (typeof nn === "string") {
|
|
12226
|
+
const tagName = transformCaseFunc(nn);
|
|
11940
12227
|
if (!ALLOWED_TAGS2[tagName] || FORBID_TAGS[tagName]) {
|
|
11941
12228
|
_neutralizeRoot(dirty);
|
|
11942
12229
|
throw typeErrorCreate("root node is forbidden and cannot be sanitized in-place");
|
|
@@ -11962,7 +12249,7 @@ function createDOMPurify() {
|
|
|
11962
12249
|
} else {
|
|
11963
12250
|
body.appendChild(importedNode);
|
|
11964
12251
|
}
|
|
11965
|
-
_sanitizeAttachedShadowRoots(
|
|
12252
|
+
_sanitizeAttachedShadowRoots(body);
|
|
11966
12253
|
} else {
|
|
11967
12254
|
if (!RETURN_DOM && !SAFE_FOR_TEMPLATES && !WHOLE_DOCUMENT && // eslint-disable-next-line unicorn/prefer-includes
|
|
11968
12255
|
dirty.indexOf("<") === -1) {
|
|
@@ -12089,38 +12376,38 @@ function createDOMPurify() {
|
|
|
12089
12376
|
}
|
|
12090
12377
|
var purify = createDOMPurify();
|
|
12091
12378
|
|
|
12092
|
-
// node_modules/.pnpm/marked@18.0.
|
|
12379
|
+
// node_modules/.pnpm/marked@18.0.12/node_modules/marked/lib/marked.esm.js
|
|
12093
12380
|
function A() {
|
|
12094
12381
|
return { async: false, breaks: false, extensions: null, gfm: true, hooks: null, pedantic: false, renderer: null, silent: false, tokenizer: null, walkTokens: null };
|
|
12095
12382
|
}
|
|
12096
|
-
var
|
|
12097
|
-
function j(
|
|
12098
|
-
|
|
12383
|
+
var T = A();
|
|
12384
|
+
function j(u3) {
|
|
12385
|
+
T = u3;
|
|
12099
12386
|
}
|
|
12100
|
-
var
|
|
12101
|
-
function I(
|
|
12387
|
+
var E = { exec: () => null };
|
|
12388
|
+
function I(u3) {
|
|
12102
12389
|
let e = [];
|
|
12103
12390
|
return (t) => {
|
|
12104
12391
|
let n = Math.max(0, Math.min(3, t - 1)), s = e[n];
|
|
12105
|
-
return s || (s =
|
|
12392
|
+
return s || (s = u3(n), e[n] = s), s;
|
|
12106
12393
|
};
|
|
12107
12394
|
}
|
|
12108
|
-
function k(
|
|
12109
|
-
let t = typeof
|
|
12110
|
-
let
|
|
12111
|
-
return
|
|
12395
|
+
function k(u3, e = "") {
|
|
12396
|
+
let t = typeof u3 == "string" ? u3 : u3.source, n = { replace: (s, r) => {
|
|
12397
|
+
let o = typeof r == "string" ? r : r.source;
|
|
12398
|
+
return o = o.replace(m.caret, "$1"), t = t.replace(s, o), n;
|
|
12112
12399
|
}, getRegex: () => new RegExp(t, e) };
|
|
12113
12400
|
return n;
|
|
12114
12401
|
}
|
|
12115
|
-
var
|
|
12402
|
+
var Te = ((u3 = "") => {
|
|
12116
12403
|
try {
|
|
12117
|
-
return !!new RegExp("(?<=1)(?<!1)" +
|
|
12404
|
+
return !!new RegExp("(?<=1)(?<!1)" + u3);
|
|
12118
12405
|
} catch {
|
|
12119
12406
|
return false;
|
|
12120
12407
|
}
|
|
12121
12408
|
})();
|
|
12122
|
-
var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (
|
|
12123
|
-
var
|
|
12409
|
+
var m = { codeRemoveIndent: /^(?: {1,4}| {0,3}\t)/gm, outputLinkReplace: /\\([\[\]])/g, indentCodeCompensation: /^(\s+)(?:```)/, beginningSpace: /^\s+/, endingHash: /#$/, startingSpaceChar: /^ /, endingSpaceChar: / $/, endingSpaceTabChar: /[ \t]$/, nonSpaceChar: /[^ ]/, newLineCharGlobal: /\n/g, tabCharGlobal: /\t/g, multipleSpaceGlobal: /\s+/g, blankLine: /^[ \t]*$/, doubleBlankLine: /\n[ \t]*\n[ \t]*$/, blockquoteStart: /^ {0,3}>/, blockquoteSetextReplace: /\n {0,3}((?:=+|-+) *)(?=\n|$)/g, blockquoteSetextReplace2: /^ {0,3}>[ \t]?/gm, listReplaceNesting: /^ {1,4}(?=( {4})*[^ ])/g, listIsTask: /^\[[ xX]\] +\S/, listReplaceTask: /^\[[ xX]\] +/, listTaskCheckbox: /\[[ xX]\]/, anyLine: /\n.*\n/, hrefBrackets: /^<(.*)>$/, tableDelimiter: /[:|]/, tableAlignChars: /^\||\| *$/g, tableRowBlankLine: /\n[ \t]*$/, tableAlignRight: /^ *-+: *$/, tableAlignCenter: /^ *:-+: *$/, tableAlignLeft: /^ *:-+ *$/, startATag: /^<a /i, endATag: /^<\/a>/i, startPreScriptTag: /^<(pre|code|kbd|script)(\s|>)/i, endPreScriptTag: /^<\/(pre|code|kbd|script)(\s|>)/i, startAngleBracket: /^</, endAngleBracket: />$/, pedanticHrefTitle: /^([^'"]*[^\s])\s+(['"])(.*)\2/, unicodeAlphaNumeric: /[\p{L}\p{N}]/u, escapeTest: /[&<>"']/, escapeReplace: /[&<>"']/g, escapeTestNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/, escapeReplaceNoEncode: /[<>"']|&(?!(#\d{1,7}|#[Xx][a-fA-F0-9]{1,6}|\w+);)/g, caret: /(^|[^\[])\^/g, percentDecode: /%25/g, findPipe: /\|/g, splitPipe: / \|/, slashPipe: /\\\|/g, carriageReturn: /\r\n|\r/g, spaceLine: /^ +$/gm, notSpaceStart: /^\S*/, endingNewline: /\n$/, listItemRegex: (u3) => new RegExp(`^( {0,3}${u3})((?:[ ][^\\n]*)?(?:\\n|$))`), nextBulletRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:[*+-]|\\d{1,9}[.)])((?:[ ][^\\n]*)?(?:\\n|$))`)), hrRegex: I((u3) => new RegExp(`^ {0,${u3}}((?:- *){3,}|(?:_ *){3,}|(?:\\* *){3,})(?:\\n+|$)`)), fencesBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}(?:\`\`\`|~~~)`)), headingBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}#`)), htmlBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}<(?:[a-z].*>|!--)`, "i")), blockquoteBeginRegex: I((u3) => new RegExp(`^ {0,${u3}}>`)) };
|
|
12410
|
+
var Oe = /^(?:[ \t]*(?:\n|$))+/;
|
|
12124
12411
|
var we = /^((?: {4}| {0,3}\t)[^\n]+(?:\n(?:[ \t]*(?:\n|$))*)?)+/;
|
|
12125
12412
|
var ye = /^ {0,3}(`{3,}(?=[^`\n]*(?:\n|$))|~{3,})([^\n]*)(?:\n|$)(?:|([\s\S]*?)(?:\n|$))(?: {0,3}\1[~`]* *(?=\n|$)|$)/;
|
|
12126
12413
|
var q = /^ {0,3}((?:-[\t ]*){3,}|(?:_[ \t]*){3,}|(?:\*[ \t]*){3,})(?:\n+|$)/;
|
|
@@ -12136,15 +12423,15 @@ var $e = k(/^ {0,3}\[(label)\]: *(?:\n[ \t]*)?([^<\s][^\s]*|<.*?>)(?:(?: +(?:\n[
|
|
|
12136
12423
|
var Le = k(/^(bull)([ \t][^\n]*?)?(?:\n|$)/).replace(/bull/g, U).getRegex();
|
|
12137
12424
|
var Q = "address|article|aside|base|basefont|blockquote|body|caption|center|col|colgroup|dd|details|dialog|dir|div|dl|dt|fieldset|figcaption|figure|footer|form|frame|frameset|h[1-6]|head|header|hr|html|iframe|legend|li|link|main|menu|menuitem|meta|nav|noframes|ol|optgroup|option|p|param|search|section|summary|table|tbody|td|tfoot|th|thead|title|tr|track|ul";
|
|
12138
12425
|
var X = /<!--(?:-?>|[\s\S]*?(?:-->|$))/;
|
|
12139
|
-
var
|
|
12140
|
-
var le = (
|
|
12141
|
-
var
|
|
12426
|
+
var ze = k("^ {0,3}(?:<(script|pre|style|textarea)[\\s>][\\s\\S]*?(?:</\\1>[^\\n]*\\n*|$)|comment[^\\n]*(\\n+|$)|<\\?[\\s\\S]*?(?:\\?>[^\\n]*\\n*|$)|<![A-Z][\\s\\S]*?(?:>[^\\n]*\\n*|$)|<!\\[CDATA\\[[\\s\\S]*?(?:\\]\\]>[^\\n]*\\n*|$)|</?(tag)(?: +|\\n|/?>)[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|<(?!script|pre|style|textarea)([a-z][a-z0-9-]*)(?:attribute)*? */?>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$)|</(?!script|pre|style|textarea)[a-z][a-z0-9-]*\\s*>(?=[ \\t]*(?:\\n|$))[\\s\\S]*?(?:(?:\\n[ ]*)+\\n|$))", "i").replace("comment", X).replace("tag", Q).replace("attribute", / +[a-zA-Z:_][\w.:-]*(?: *= *"[^"\n]*"| *= *'[^'\n]*'| *= *[^\s"'=<>`]+)?/).getRegex();
|
|
12427
|
+
var le = (u3) => k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("|table", "").replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", u3).replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
|
|
12428
|
+
var Ee = le(/ {0,3}(?:[*+-]|1[.)])[ \t]+[^ \t\n]/);
|
|
12142
12429
|
var Me = le(/ {0,3}(?:[*+-]|\d{1,9}[.)])(?:[ \t]|\n|$)/);
|
|
12143
12430
|
var Ae = k(/^( {0,3}> ?(paragraph|[^\n]*)(?:\n|$))+/).replace("paragraph", Me).getRegex();
|
|
12144
|
-
var J = { blockquote: Ae, code: we, def: $e, fences: ye, heading: Pe, hr: q, html:
|
|
12431
|
+
var J = { blockquote: Ae, code: we, def: $e, fences: ye, heading: Pe, hr: q, html: ze, lheading: ae, list: Le, newline: Oe, paragraph: Ee, table: E, text: _e };
|
|
12145
12432
|
var se = k("^ *([^\\n ].*)\\n {0,3}((?:\\| *)?:?-+:? *(?:\\| *:?-+:? *)*(?:\\| *)?)(?:\\n((?:(?! *\\n|hr|heading|blockquote|code|fences|list|html).*(?:\\n|$))*)\\n*|$)").replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("blockquote", " {0,3}>").replace("code", "(?: {4}| {0,3} )[^\\n]").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex();
|
|
12146
12433
|
var Ie = { ...J, lheading: Se, table: se, paragraph: k(K).replace("hr", q).replace("heading", " {0,3}#{1,6}(?:\\s|$)").replace("|lheading", "").replace("table", se).replace("blockquote", " {0,3}>").replace("fences", " {0,3}(?:`{3,}(?=[^`\\n]*(?:\\n|$))|~~~)[^\\n]*(?:\\n|$)").replace("list", " {0,3}(?:[*+-]|1[.)])[ \\t]+[^ \\t\\n]").replace("html", "</?(?:tag)(?: +|\\n|/?>)|<(?:script|pre|style|textarea|!--)").replace("tag", Q).getRegex() };
|
|
12147
|
-
var Ce = { ...J, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences:
|
|
12434
|
+
var Ce = { ...J, html: k(`^ *(?:comment *(?:\\n|\\s*$)|<(tag)[\\s\\S]+?</\\1> *(?:\\n{2,}|\\s*$)|<tag(?:"[^"]*"|'[^']*'|\\s[^'"/>\\s]*)*?/?> *(?:\\n{2,}|\\s*$))`).replace("comment", X).replace(/tag/g, "(?!(?:a|em|strong|small|s|cite|q|dfn|abbr|data|time|code|var|samp|kbd|sub|sup|i|b|u|mark|ruby|rt|rp|bdi|bdo|span|br|wbr|ins|del|img)\\b)\\w+(?!:|[^\\w\\s@]*@)\\b").getRegex(), def: /^ *\[([^\]]+)\]: *<?([^\s>]+)>?(?: +(["(][^\n]+[")]))? *(?:\n+|$)/, heading: /^(#{1,6})(.*)(?:\n+|$)/, fences: E, lheading: /^(.+?)\n {0,3}(=+|-+) *(?:\n+|$)/, paragraph: k(K).replace("hr", q).replace("heading", ` *#{1,6} *[^
|
|
12148
12435
|
]`).replace("lheading", ae).replace("|table", "").replace("blockquote", " {0,3}>").replace("|fences", "").replace("|list", "").replace("|html", "").replace("|tag", "").getRegex() };
|
|
12149
12436
|
var Be = /^\\([!"#$%&'()*+,\-./:;<=>?@\[\]\\^_`{|}~])/;
|
|
12150
12437
|
var De = /^(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/;
|
|
@@ -12158,7 +12445,7 @@ var He = /[\p{Pi}\p{Ps}"']/u;
|
|
|
12158
12445
|
var pe = /(?!~)[\p{P}\p{S}]/u;
|
|
12159
12446
|
var Ze = /(?!~)[\s\p{P}\p{S}]/u;
|
|
12160
12447
|
var Ge = /(?:[^\s\p{P}\p{S}]|~)/u;
|
|
12161
|
-
var Qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-",
|
|
12448
|
+
var Qe = k(/link|precode-code|html/, "g").replace("link", /\[(?:[^\[\]`]|(?<a>`+)[^`]+\k<a>(?!`))*?\]\((?:\\[\s\S]|[^\\\(\)]|\((?:\\[\s\S]|[^\\\(\)])*\))*\)/).replace("precode-", Te ? "(?<!`)()" : "(^^|[^`])").replace("code", /(?<b>`+)[^`]+\k<b>(?!`)/).replace("html", /<(?! )[^<>]*?>/).getRegex();
|
|
12162
12449
|
var ce = /^(?:\*+(?:((?!\*)punct)|([^\s*]))?)|^_+(?:((?!_)punct)|([^\s_]))?/;
|
|
12163
12450
|
var Ne = k(ce, "u").replace(/punct/g, _).getRegex();
|
|
12164
12451
|
var je = k(ce, "u").replace(/punct/g, pe).getRegex();
|
|
@@ -12178,106 +12465,107 @@ var rt = k(nt, "gu").replace(/notPunctSpace/g, v).replace(/punctSpace/g, C).repl
|
|
|
12178
12465
|
var st = k(/\\(punct)/, "gu").replace(/punct/g, _).getRegex();
|
|
12179
12466
|
var it = k(/^<(scheme:[^\s\x00-\x1f<>]*|email)>/).replace("scheme", /[a-zA-Z][a-zA-Z0-9+.-]{1,31}/).replace("email", /[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+(@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+(?![-_])/).getRegex();
|
|
12180
12467
|
var ot = k(X).replace("(?:-->|$)", "-->").getRegex();
|
|
12181
|
-
var at = k("^comment|^</[a-zA-Z][
|
|
12182
|
-
var
|
|
12183
|
-
var
|
|
12468
|
+
var at = k("^comment|^</[a-zA-Z][a-zA-Z0-9-]*\\s*>|^<[a-zA-Z][a-zA-Z0-9-]*(?:attribute)*?\\s*/?>|^<\\?[\\s\\S]*?\\?>|^<![a-zA-Z]+\\s[\\s\\S]*?>|^<!\\[CDATA\\[[\\s\\S]*?\\]\\]>").replace("comment", ot).replace("attribute", /\s+[a-zA-Z:_][\w.:-]*(?:\s*=\s*"[^"]*"|\s*=\s*'[^']*'|\s*=\s*[^\s"'=<>`]+)?/).getRegex();
|
|
12469
|
+
var lt = /\[(?:\\[\s\S]|[^\[\]\\])*\]/;
|
|
12470
|
+
var G = k(/(?:\[(?:brackets|\\[\s\S]|[^\[\]\\])*\]|\\[\s\S]|`+(?!`)[^`]*?`+(?!`)|``+(?=\])|[^\[\]\\`])*?/).replace("brackets", lt).getRegex();
|
|
12471
|
+
var ut = k(/^!?\[(label)\]\(\s*(href)(?:(?:[ \t]+(?:\n[ \t]*)?|\n[ \t]*)(title))?\s*\)/).replace("label", G).replace("href", /<(?:\\.|[^\n<>\\])+>|[^ \t\n\x00-\x1f]+|(?=\))/).replace("title", /"(?:\\"?|[^"\\])*"|'(?:\\'?|[^'\\])*'|\((?:\\\)?|[^)\\])*\)/).getRegex();
|
|
12184
12472
|
var ke = k(/^!?\[(label)\]\[(ref)\]/).replace("label", G).replace("ref", W).getRegex();
|
|
12185
12473
|
var de = k(/^!?\[(ref)\](?:\[\])?/).replace("ref", W).getRegex();
|
|
12186
|
-
var
|
|
12474
|
+
var pt = k("reflink|nolink(?!\\()", "g").replace("reflink", ke).replace("nolink", de).getRegex();
|
|
12187
12475
|
var ie = /[hH][tT][tT][pP][sS]?|[fF][tT][pP]/;
|
|
12188
|
-
var V = { _backpedal:
|
|
12189
|
-
var
|
|
12190
|
-
var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![-
|
|
12191
|
-
var
|
|
12476
|
+
var V = { _backpedal: E, anyPunctuation: st, autolink: it, blockSkip: Qe, br: ue, code: De, del: E, delLDelim: E, delRDelim: E, emStrongLDelim: Ne, emStrongRDelimAst: Ke, emStrongRDelimUnd: Ve, escape: Be, link: ut, nolink: de, punctuation: ve, reflink: ke, reflinkSearch: pt, tag: at, text: qe, url: E };
|
|
12477
|
+
var ct = { ...V, emStrongLDelim: Ue, emStrongRDelimAst: Je, emStrongRDelimUnd: et, link: k(/^!?\[(label)\]\((.*?)\)/).replace("label", G).getRegex(), reflink: k(/^!?\[(label)\]\s*\[([^\]]*)\]/).replace("label", G).getRegex() };
|
|
12478
|
+
var F = { ...V, emStrongRDelimAst: We, emStrongLDelim: je, delLDelim: tt, delRDelim: rt, url: k(/^((?:protocol):\/\/|www\.)(?:[a-zA-Z0-9\-]+\.?)+[^\s<]*|^email/).replace("protocol", ie).replace("email", /[A-Za-z0-9._+-]+(@)[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9-_]*[a-zA-Z0-9])+(?![\w-])/).getRegex(), _backpedal: /(?:[^?!.,:;*_'"~()&]+|\([^)]*\)|&(?![a-zA-Z0-9]+;$)|[?!.,:;*_'"~)]+(?!$))+/, del: /^(~~?)(?=[^\s~])((?:\\[\s\S]|[^\\])*?(?:\\[\s\S]|[^\s~\\]))\1(?=[^~]|$)/, text: k(/^(`+|~+|[^`~])(?:(?=[`~])|(?= {2,}\n)|(?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)|[\s\S]*?(?:(?=[\\<!\[`*~_]|\b_|protocol:\/\/|www\.|$)|[^ ](?= {2,}\n)|[^a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-](?=[a-zA-Z0-9.!#$%&'*+\/=?_`{\|}~-]+@)))/).replace("protocol", ie).getRegex() };
|
|
12479
|
+
var ht = { ...F, br: k(ue).replace("{2,}", "*").getRegex(), text: k(F.text).replace("\\b_", "\\b_| {2,}\\n").replace(/\{2,\}/g, "*").getRegex() };
|
|
12192
12480
|
var H = { normal: J, gfm: Ie, pedantic: Ce };
|
|
12193
|
-
var B = { normal: V, gfm: F, breaks:
|
|
12194
|
-
var
|
|
12195
|
-
var ge = (
|
|
12196
|
-
function
|
|
12481
|
+
var B = { normal: V, gfm: F, breaks: ht, pedantic: ct };
|
|
12482
|
+
var kt = { "&": "&", "<": "<", ">": ">", '"': """, "'": "'" };
|
|
12483
|
+
var ge = (u3) => kt[u3];
|
|
12484
|
+
function R(u3, e) {
|
|
12197
12485
|
if (e) {
|
|
12198
|
-
if (m.escapeTest.test(
|
|
12199
|
-
} else if (m.escapeTestNoEncode.test(
|
|
12200
|
-
return
|
|
12486
|
+
if (m.escapeTest.test(u3)) return u3.replace(m.escapeReplace, ge);
|
|
12487
|
+
} else if (m.escapeTestNoEncode.test(u3)) return u3.replace(m.escapeReplaceNoEncode, ge);
|
|
12488
|
+
return u3;
|
|
12201
12489
|
}
|
|
12202
|
-
function Y(
|
|
12490
|
+
function Y(u3) {
|
|
12203
12491
|
try {
|
|
12204
|
-
|
|
12492
|
+
u3 = encodeURI(u3).replace(m.percentDecode, "%");
|
|
12205
12493
|
} catch {
|
|
12206
12494
|
return null;
|
|
12207
12495
|
}
|
|
12208
|
-
return
|
|
12496
|
+
return u3;
|
|
12209
12497
|
}
|
|
12210
|
-
function ee(
|
|
12211
|
-
let t =
|
|
12212
|
-
let
|
|
12213
|
-
for (; --a >= 0 &&
|
|
12214
|
-
return
|
|
12498
|
+
function ee(u3, e) {
|
|
12499
|
+
let t = u3.replace(m.findPipe, (r, o, i) => {
|
|
12500
|
+
let l = false, a = o;
|
|
12501
|
+
for (; --a >= 0 && i[a] === "\\"; ) l = !l;
|
|
12502
|
+
return l ? "|" : " |";
|
|
12215
12503
|
}), n = t.split(m.splitPipe), s = 0;
|
|
12216
12504
|
if (n[0].trim() || n.shift(), n.length > 0 && !n.at(-1)?.trim() && n.pop(), e) if (n.length > e) n.splice(e);
|
|
12217
12505
|
else for (; n.length < e; ) n.push("");
|
|
12218
12506
|
for (; s < n.length; s++) n[s] = n[s].trim().replace(m.slashPipe, "|");
|
|
12219
12507
|
return n;
|
|
12220
12508
|
}
|
|
12221
|
-
function $(
|
|
12222
|
-
let n =
|
|
12509
|
+
function $(u3, e, t) {
|
|
12510
|
+
let n = u3.length;
|
|
12223
12511
|
if (n === 0) return "";
|
|
12224
12512
|
let s = 0;
|
|
12225
12513
|
for (; s < n; ) {
|
|
12226
|
-
let r =
|
|
12514
|
+
let r = u3.charAt(n - s - 1);
|
|
12227
12515
|
if (r === e && !t) s++;
|
|
12228
12516
|
else if (r !== e && t) s++;
|
|
12229
12517
|
else break;
|
|
12230
12518
|
}
|
|
12231
|
-
return
|
|
12519
|
+
return u3.slice(0, n - s);
|
|
12232
12520
|
}
|
|
12233
|
-
function te(
|
|
12234
|
-
let e =
|
|
12521
|
+
function te(u3) {
|
|
12522
|
+
let e = u3.split(`
|
|
12235
12523
|
`), t = e.length - 1;
|
|
12236
12524
|
for (; t >= 0 && m.blankLine.test(e[t]); ) t--;
|
|
12237
|
-
return e.length - t <= 2 ?
|
|
12525
|
+
return e.length - t <= 2 ? u3 : e.slice(0, t + 1).join(`
|
|
12238
12526
|
`);
|
|
12239
12527
|
}
|
|
12240
|
-
function fe(
|
|
12241
|
-
if (
|
|
12528
|
+
function fe(u3, e) {
|
|
12529
|
+
if (u3.indexOf(e[1]) === -1) return -1;
|
|
12242
12530
|
let t = 0;
|
|
12243
|
-
for (let n = 0; n <
|
|
12244
|
-
else if (
|
|
12245
|
-
else if (
|
|
12531
|
+
for (let n = 0; n < u3.length; n++) if (u3[n] === "\\") n++;
|
|
12532
|
+
else if (u3[n] === e[0]) t++;
|
|
12533
|
+
else if (u3[n] === e[1] && (t--, t < 0)) return n;
|
|
12246
12534
|
return t > 0 ? -2 : -1;
|
|
12247
12535
|
}
|
|
12248
|
-
function me(
|
|
12536
|
+
function me(u3, e = 0) {
|
|
12249
12537
|
let t = e, n = "";
|
|
12250
|
-
for (let s of
|
|
12538
|
+
for (let s of u3) if (s === " ") {
|
|
12251
12539
|
let r = 4 - t % 4;
|
|
12252
12540
|
n += " ".repeat(r), t += r;
|
|
12253
12541
|
} else n += s, t++;
|
|
12254
12542
|
return n;
|
|
12255
12543
|
}
|
|
12256
|
-
function xe(
|
|
12257
|
-
let r = e.href,
|
|
12544
|
+
function xe(u3, e, t, n, s) {
|
|
12545
|
+
let r = e.href, o = e.title || null, i = u3[1].replace(s.other.outputLinkReplace, "$1"), l = u3[0].charAt(0) === "!";
|
|
12258
12546
|
n.state.inLink = true;
|
|
12259
12547
|
let a = n.state.linkEmitted, p = n.state.inRawBlock;
|
|
12260
12548
|
n.state.linkEmitted = false;
|
|
12261
|
-
let c = n.inlineTokens(
|
|
12262
|
-
if (n.state.linkEmitted = a, n.state.inLink = false, !
|
|
12549
|
+
let c = n.inlineTokens(i), h = n.state.linkEmitted;
|
|
12550
|
+
if (n.state.linkEmitted = a, n.state.inLink = false, !l) {
|
|
12263
12551
|
if (h) {
|
|
12264
12552
|
n.state.inRawBlock = p;
|
|
12265
12553
|
return;
|
|
12266
12554
|
}
|
|
12267
12555
|
n.state.linkEmitted = true;
|
|
12268
12556
|
}
|
|
12269
|
-
return { type:
|
|
12557
|
+
return { type: l ? "image" : "link", raw: t, href: r, title: o, text: i, tokens: c };
|
|
12270
12558
|
}
|
|
12271
|
-
function
|
|
12272
|
-
let n =
|
|
12559
|
+
function dt(u3, e, t) {
|
|
12560
|
+
let n = u3.match(t.other.indentCodeCompensation);
|
|
12273
12561
|
if (n === null) return e;
|
|
12274
12562
|
let s = n[1];
|
|
12275
12563
|
return e.split(`
|
|
12276
12564
|
`).map((r) => {
|
|
12277
|
-
let
|
|
12278
|
-
if (
|
|
12279
|
-
let [
|
|
12280
|
-
return
|
|
12565
|
+
let o = r.match(t.other.beginningSpace);
|
|
12566
|
+
if (o === null) return r;
|
|
12567
|
+
let [i] = o;
|
|
12568
|
+
return r.slice(Math.min(i.length, s.length));
|
|
12281
12569
|
}).join(`
|
|
12282
12570
|
`);
|
|
12283
12571
|
}
|
|
@@ -12286,7 +12574,7 @@ var y = class {
|
|
|
12286
12574
|
rules;
|
|
12287
12575
|
lexer;
|
|
12288
12576
|
constructor(e) {
|
|
12289
|
-
this.options = e ||
|
|
12577
|
+
this.options = e || T;
|
|
12290
12578
|
}
|
|
12291
12579
|
space(e) {
|
|
12292
12580
|
let t = this.rules.block.newline.exec(e);
|
|
@@ -12302,7 +12590,7 @@ var y = class {
|
|
|
12302
12590
|
fences(e) {
|
|
12303
12591
|
let t = this.rules.block.fences.exec(e);
|
|
12304
12592
|
if (t) {
|
|
12305
|
-
let n = t[0], s =
|
|
12593
|
+
let n = t[0], s = dt(n, t[3] || "", this.rules);
|
|
12306
12594
|
return { type: "code", raw: n, lang: t[2] ? t[2].trim().replace(this.rules.inline.anyPunctuation, "$1") : t[2], text: s };
|
|
12307
12595
|
}
|
|
12308
12596
|
}
|
|
@@ -12312,7 +12600,7 @@ var y = class {
|
|
|
12312
12600
|
let n = t[2].trim();
|
|
12313
12601
|
if (this.rules.other.endingHash.test(n)) {
|
|
12314
12602
|
let s = $(n, "#");
|
|
12315
|
-
(this.options.pedantic || !s || this.rules.other.
|
|
12603
|
+
(this.options.pedantic || !s || this.rules.other.endingSpaceTabChar.test(s)) && (n = s.trim());
|
|
12316
12604
|
}
|
|
12317
12605
|
return { type: "heading", raw: $(t[0], `
|
|
12318
12606
|
`), depth: t[1].length, text: n, tokens: this.lexer.inline(n) };
|
|
@@ -12328,40 +12616,40 @@ var y = class {
|
|
|
12328
12616
|
if (t) {
|
|
12329
12617
|
let n = $(t[0], `
|
|
12330
12618
|
`).split(`
|
|
12331
|
-
`), s = "", r = "",
|
|
12619
|
+
`), s = "", r = "", o = [];
|
|
12332
12620
|
for (; n.length > 0; ) {
|
|
12333
|
-
let
|
|
12334
|
-
for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a]))
|
|
12335
|
-
else if (!
|
|
12621
|
+
let i = false, l = [], a;
|
|
12622
|
+
for (a = 0; a < n.length; a++) if (this.rules.other.blockquoteStart.test(n[a])) l.push(n[a]), i = true;
|
|
12623
|
+
else if (!i) l.push(n[a]);
|
|
12336
12624
|
else break;
|
|
12337
12625
|
n = n.slice(a);
|
|
12338
|
-
let p =
|
|
12626
|
+
let p = l.join(`
|
|
12339
12627
|
`), c = p.replace(this.rules.other.blockquoteSetextReplace, `
|
|
12340
12628
|
$1`).replace(this.rules.other.blockquoteSetextReplace2, "");
|
|
12341
12629
|
s = s ? `${s}
|
|
12342
12630
|
${p}` : p, r = r ? `${r}
|
|
12343
12631
|
${c}` : c;
|
|
12344
12632
|
let h = this.lexer.state.top;
|
|
12345
|
-
if (this.lexer.state.top = true, this.lexer.blockTokens(c,
|
|
12346
|
-
let d =
|
|
12633
|
+
if (this.lexer.state.top = true, this.lexer.blockTokens(c, o, true), this.lexer.state.top = h, n.length === 0) break;
|
|
12634
|
+
let d = o.at(-1);
|
|
12347
12635
|
if (d?.type === "code") break;
|
|
12348
12636
|
if (d?.type === "blockquote") {
|
|
12349
12637
|
let O = d, g = n.join(`
|
|
12350
12638
|
`), w = O.raw + `
|
|
12351
|
-
` + g.replace(this.rules.other.blockquoteSetextReplace2, ""),
|
|
12352
|
-
|
|
12353
|
-
${g}`, r = r.substring(0, r.length - O.text.length) +
|
|
12639
|
+
` + g.replace(this.rules.other.blockquoteSetextReplace2, ""), z = this.blockquote(w);
|
|
12640
|
+
o[o.length - 1] = z, s = `${s}
|
|
12641
|
+
${g}`, r = r.substring(0, r.length - O.text.length) + z.text;
|
|
12354
12642
|
break;
|
|
12355
12643
|
} else if (d?.type === "list") {
|
|
12356
12644
|
let O = d, g = O.raw + `
|
|
12357
12645
|
` + n.join(`
|
|
12358
12646
|
`), w = this.list(g);
|
|
12359
|
-
|
|
12647
|
+
o[o.length - 1] = w, s = s.substring(0, s.length - d.raw.length) + w.raw, r = r.substring(0, r.length - O.raw.length) + w.raw, n = g.substring(o.at(-1).raw.length).split(`
|
|
12360
12648
|
`);
|
|
12361
12649
|
continue;
|
|
12362
12650
|
}
|
|
12363
12651
|
}
|
|
12364
|
-
return { type: "blockquote", raw: s, tokens:
|
|
12652
|
+
return { type: "blockquote", raw: s, tokens: o, text: r };
|
|
12365
12653
|
}
|
|
12366
12654
|
}
|
|
12367
12655
|
list(e) {
|
|
@@ -12369,25 +12657,25 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12369
12657
|
if (t) {
|
|
12370
12658
|
let n = t[1].trim(), s = n.length > 1, r = { type: "list", raw: "", ordered: s, start: s ? +n.slice(0, -1) : "", loose: false, items: [] };
|
|
12371
12659
|
n = s ? `\\d{1,9}\\${n.slice(-1)}` : `\\${n}`, this.options.pedantic && (n = s ? n : "[*+-]");
|
|
12372
|
-
let
|
|
12660
|
+
let o = this.rules.other.listItemRegex(n), i = false;
|
|
12373
12661
|
for (; e; ) {
|
|
12374
12662
|
let a = false, p = "", c = "";
|
|
12375
|
-
if (!(t =
|
|
12663
|
+
if (!(t = o.exec(e)) || this.rules.block.hr.test(e)) break;
|
|
12376
12664
|
p = t[0], e = e.substring(p.length);
|
|
12377
12665
|
let h = me(t[2].split(`
|
|
12378
12666
|
`, 1)[0], t[1].length), d = e.split(`
|
|
12379
12667
|
`, 1)[0], O = !h.trim(), g = 0;
|
|
12380
12668
|
if (this.options.pedantic ? (g = 2, c = h.trimStart()) : O ? g = t[1].length + 1 : (g = h.search(this.rules.other.nonSpaceChar), g = g > 4 ? 1 : g, c = h.slice(g), g += t[1].length), O && this.rules.other.blankLine.test(d) && (p += d + `
|
|
12381
12669
|
`, e = e.substring(d.length + 1), a = true), !a) {
|
|
12382
|
-
let w = this.rules.other.nextBulletRegex(g),
|
|
12670
|
+
let w = this.rules.other.nextBulletRegex(g), z = this.rules.other.hrRegex(g), ne = this.rules.other.fencesBeginRegex(g), re = this.rules.other.headingBeginRegex(g), be = this.rules.other.htmlBeginRegex(g), Re = this.rules.other.blockquoteBeginRegex(g);
|
|
12383
12671
|
for (; e; ) {
|
|
12384
12672
|
let N = e.split(`
|
|
12385
12673
|
`, 1)[0], D;
|
|
12386
|
-
if (d = N, this.options.pedantic ? (d = d.replace(this.rules.other.listReplaceNesting, " "), D = d) : D = d.replace(this.rules.other.tabCharGlobal, " "), ne.test(d) || re.test(d) || be.test(d) || Re.test(d) || w.test(d) ||
|
|
12674
|
+
if (d = N, this.options.pedantic ? (d = d.replace(this.rules.other.listReplaceNesting, " "), D = d) : D = d.replace(this.rules.other.tabCharGlobal, " "), ne.test(d) || re.test(d) || be.test(d) || Re.test(d) || w.test(d) || z.test(d)) break;
|
|
12387
12675
|
if (D.search(this.rules.other.nonSpaceChar) >= g || !d.trim()) c += `
|
|
12388
12676
|
` + D.slice(g);
|
|
12389
12677
|
else {
|
|
12390
|
-
if (O || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) ||
|
|
12678
|
+
if (O || h.replace(this.rules.other.tabCharGlobal, " ").search(this.rules.other.nonSpaceChar) >= 4 || ne.test(h) || re.test(h) || z.test(h)) break;
|
|
12391
12679
|
c += `
|
|
12392
12680
|
` + d;
|
|
12393
12681
|
}
|
|
@@ -12395,10 +12683,10 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12395
12683
|
`, e = e.substring(N.length + 1), h = D.slice(g);
|
|
12396
12684
|
}
|
|
12397
12685
|
}
|
|
12398
|
-
r.loose || (
|
|
12686
|
+
r.loose || (i ? r.loose = true : this.rules.other.doubleBlankLine.test(p) && (i = true)), r.items.push({ type: "list_item", raw: p, task: !!this.options.gfm && this.rules.other.listIsTask.test(c), loose: false, text: c, tokens: [] }), r.raw += p;
|
|
12399
12687
|
}
|
|
12400
|
-
let
|
|
12401
|
-
if (
|
|
12688
|
+
let l = r.items.at(-1);
|
|
12689
|
+
if (l) l.raw = l.raw.trimEnd(), l.text = l.text.trimEnd();
|
|
12402
12690
|
else return;
|
|
12403
12691
|
r.raw = r.raw.trimEnd();
|
|
12404
12692
|
for (let a of r.items) if (this.lexer.state.top = false, a.tokens = this.lexer.blockTokens(a.text, []), !r.loose) {
|
|
@@ -12446,13 +12734,13 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12446
12734
|
let t = this.rules.block.table.exec(e);
|
|
12447
12735
|
if (!t || !this.rules.other.tableDelimiter.test(t[2])) return;
|
|
12448
12736
|
let n = ee(t[1]), s = t[2].replace(this.rules.other.tableAlignChars, "").split("|"), r = t[3]?.trim() ? t[3].replace(this.rules.other.tableRowBlankLine, "").split(`
|
|
12449
|
-
`) : [],
|
|
12737
|
+
`) : [], o = { type: "table", raw: $(t[0], `
|
|
12450
12738
|
`), header: [], align: [], rows: [] };
|
|
12451
12739
|
if (n.length === s.length) {
|
|
12452
|
-
for (let
|
|
12453
|
-
for (let
|
|
12454
|
-
for (let
|
|
12455
|
-
return
|
|
12740
|
+
for (let i of s) this.rules.other.tableAlignRight.test(i) ? o.align.push("right") : this.rules.other.tableAlignCenter.test(i) ? o.align.push("center") : this.rules.other.tableAlignLeft.test(i) ? o.align.push("left") : o.align.push(null);
|
|
12741
|
+
for (let i = 0; i < n.length; i++) o.header.push({ text: n[i], tokens: this.lexer.inline(n[i]), header: true, align: o.align[i] });
|
|
12742
|
+
for (let i of r) o.rows.push(ee(i, o.header.length).map((l, a) => ({ text: l, tokens: this.lexer.inline(l), header: false, align: o.align[a] })));
|
|
12743
|
+
return o;
|
|
12456
12744
|
}
|
|
12457
12745
|
}
|
|
12458
12746
|
lheading(e) {
|
|
@@ -12489,20 +12777,20 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12489
12777
|
let n = t[2].trim();
|
|
12490
12778
|
if (!this.options.pedantic && this.rules.other.startAngleBracket.test(n)) {
|
|
12491
12779
|
if (!this.rules.other.endAngleBracket.test(n)) return;
|
|
12492
|
-
let
|
|
12493
|
-
if ((n.length -
|
|
12780
|
+
let o = $(n.slice(0, -1), "\\");
|
|
12781
|
+
if ((n.length - o.length) % 2 === 0) return;
|
|
12494
12782
|
} else {
|
|
12495
|
-
let
|
|
12496
|
-
if (
|
|
12497
|
-
if (
|
|
12498
|
-
let
|
|
12499
|
-
t[2] = t[2].substring(0,
|
|
12783
|
+
let o = fe(t[2], "()");
|
|
12784
|
+
if (o === -2) return;
|
|
12785
|
+
if (o > -1) {
|
|
12786
|
+
let l = (t[0].indexOf("!") === 0 ? 5 : 4) + t[1].length + o;
|
|
12787
|
+
t[2] = t[2].substring(0, o), t[0] = t[0].substring(0, l).trim(), t[3] = "";
|
|
12500
12788
|
}
|
|
12501
12789
|
}
|
|
12502
12790
|
let s = t[2], r = "";
|
|
12503
12791
|
if (this.options.pedantic) {
|
|
12504
|
-
let
|
|
12505
|
-
|
|
12792
|
+
let o = this.rules.other.pedanticHrefTitle.exec(s);
|
|
12793
|
+
o && (s = o[1], r = o[3]);
|
|
12506
12794
|
} else r = t[3] ? t[3].slice(1, -1) : "";
|
|
12507
12795
|
return s = s.trim(), this.rules.other.startAngleBracket.test(s) && (this.options.pedantic && !this.rules.other.endAngleBracket.test(n) ? s = s.slice(1) : s = s.slice(1, -1)), xe(t, { href: s && s.replace(this.rules.inline.anyPunctuation, "$1"), title: r && r.replace(this.rules.inline.anyPunctuation, "$1") }, t[0], this.lexer, this.rules);
|
|
12508
12796
|
}
|
|
@@ -12512,8 +12800,8 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12512
12800
|
if ((n = this.rules.inline.reflink.exec(e)) || (n = this.rules.inline.nolink.exec(e))) {
|
|
12513
12801
|
let s = (n[2] || n[1]).replace(this.rules.other.multipleSpaceGlobal, " "), r = t[s.toLowerCase()];
|
|
12514
12802
|
if (!r) {
|
|
12515
|
-
let
|
|
12516
|
-
return { type: "text", raw:
|
|
12803
|
+
let o = n[0].charAt(0);
|
|
12804
|
+
return { type: "text", raw: o, text: o };
|
|
12517
12805
|
}
|
|
12518
12806
|
return xe(n, r, n[0], this.lexer, this.rules);
|
|
12519
12807
|
}
|
|
@@ -12522,25 +12810,25 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12522
12810
|
let s = this.rules.inline.emStrongLDelim.exec(e);
|
|
12523
12811
|
if (!s || !s[1] && !s[2] && !s[3] && !s[4] || s[4] && n.match(this.rules.other.unicodeAlphaNumeric)) return;
|
|
12524
12812
|
if (!(s[1] || s[3] || "") || !n || this.rules.inline.punctuation.exec(n)) {
|
|
12525
|
-
let
|
|
12526
|
-
for (d.lastIndex = 0, t = t.slice(-1 * e.length +
|
|
12527
|
-
if (
|
|
12528
|
-
if (
|
|
12529
|
-
a +=
|
|
12813
|
+
let o = [...s[0]].length - 1, i, l, a = o, p = 0, c = s[0][0], h = n === c, d = c === "*" ? this.rules.inline.emStrongRDelimAst : this.rules.inline.emStrongRDelimUnd;
|
|
12814
|
+
for (d.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = d.exec(t)) !== null; ) {
|
|
12815
|
+
if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i) continue;
|
|
12816
|
+
if (l = [...i].length, s[3] || s[4]) {
|
|
12817
|
+
a += l;
|
|
12530
12818
|
continue;
|
|
12531
12819
|
} else if (s[5] || s[6]) {
|
|
12532
|
-
if (
|
|
12533
|
-
p +=
|
|
12820
|
+
if (o % 3 && !((o + l) % 3)) {
|
|
12821
|
+
p += l;
|
|
12534
12822
|
continue;
|
|
12535
12823
|
}
|
|
12536
12824
|
if (h) break;
|
|
12537
12825
|
}
|
|
12538
|
-
if (a -=
|
|
12539
|
-
|
|
12540
|
-
let O = [...s[0]][0].length, g = e.slice(0,
|
|
12541
|
-
if (Math.min(
|
|
12542
|
-
let
|
|
12543
|
-
return { type: "em", raw: g, text:
|
|
12826
|
+
if (a -= l, a > 0) continue;
|
|
12827
|
+
l = Math.min(l, l + a + p);
|
|
12828
|
+
let O = [...s[0]][0].length, g = e.slice(0, o + s.index + O + l);
|
|
12829
|
+
if (Math.min(o, l) % 2) {
|
|
12830
|
+
let z = g.slice(1, -1);
|
|
12831
|
+
return { type: "em", raw: g, text: z, tokens: this.lexer.inlineTokens(z) };
|
|
12544
12832
|
}
|
|
12545
12833
|
let w = g.slice(2, -2);
|
|
12546
12834
|
return { type: "strong", raw: g, text: w, tokens: this.lexer.inlineTokens(w) };
|
|
@@ -12562,16 +12850,16 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12562
12850
|
let s = this.rules.inline.delLDelim.exec(e);
|
|
12563
12851
|
if (!s) return;
|
|
12564
12852
|
if (!(s[1] || "") || !n || this.rules.inline.punctuation.exec(n)) {
|
|
12565
|
-
let
|
|
12566
|
-
for (p.lastIndex = 0, t = t.slice(-1 * e.length +
|
|
12567
|
-
if (
|
|
12853
|
+
let o = [...s[0]].length - 1, i, l, a = o, p = this.rules.inline.delRDelim;
|
|
12854
|
+
for (p.lastIndex = 0, t = t.slice(-1 * e.length + o); (s = p.exec(t)) !== null; ) {
|
|
12855
|
+
if (i = s[1] || s[2] || s[3] || s[4] || s[5] || s[6], !i || (l = [...i].length, l !== o)) continue;
|
|
12568
12856
|
if (s[3] || s[4]) {
|
|
12569
|
-
a +=
|
|
12857
|
+
a += l;
|
|
12570
12858
|
continue;
|
|
12571
12859
|
}
|
|
12572
|
-
if (a -=
|
|
12573
|
-
|
|
12574
|
-
let c = [...s[0]][0].length, h = e.slice(0,
|
|
12860
|
+
if (a -= l, a > 0) continue;
|
|
12861
|
+
l = Math.min(l, l + a);
|
|
12862
|
+
let c = [...s[0]][0].length, h = e.slice(0, o + s.index + c + l), d = h.slice(o, -o);
|
|
12575
12863
|
return { type: "del", raw: h, text: d, tokens: this.lexer.inlineTokens(d) };
|
|
12576
12864
|
}
|
|
12577
12865
|
}
|
|
@@ -12580,7 +12868,7 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12580
12868
|
let t = this.rules.inline.autolink.exec(e);
|
|
12581
12869
|
if (t) {
|
|
12582
12870
|
let n, s;
|
|
12583
|
-
return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
|
|
12871
|
+
return t[2] === "@" ? (n = t[1], s = "mailto:" + n) : (n = t[1], s = n), { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
|
|
12584
12872
|
}
|
|
12585
12873
|
}
|
|
12586
12874
|
url(e) {
|
|
@@ -12595,7 +12883,7 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12595
12883
|
while (r !== t[0]);
|
|
12596
12884
|
n = t[0], t[1] === "www." ? s = "http://" + t[0] : s = t[0];
|
|
12597
12885
|
}
|
|
12598
|
-
return { type: "link", raw: t[0], text: n, href: s, tokens: [{ type: "text", raw: n, text: n }] };
|
|
12886
|
+
return { type: "link", raw: t[0], text: n, href: s, autolink: true, tokens: [{ type: "text", raw: n, text: n }] };
|
|
12599
12887
|
}
|
|
12600
12888
|
}
|
|
12601
12889
|
inlineText(e) {
|
|
@@ -12606,14 +12894,14 @@ ${g}`, r = r.substring(0, r.length - O.text.length) + E.text;
|
|
|
12606
12894
|
}
|
|
12607
12895
|
}
|
|
12608
12896
|
};
|
|
12609
|
-
var x = class
|
|
12897
|
+
var x = class u {
|
|
12610
12898
|
tokens;
|
|
12611
12899
|
options;
|
|
12612
12900
|
state;
|
|
12613
12901
|
inlineQueue;
|
|
12614
12902
|
tokenizer;
|
|
12615
12903
|
constructor(e) {
|
|
12616
|
-
this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e ||
|
|
12904
|
+
this.tokens = [], this.tokens.links = /* @__PURE__ */ Object.create(null), this.options = e || T, this.options.tokenizer = this.options.tokenizer || new y(), this.tokenizer = this.options.tokenizer, this.tokenizer.options = this.options, this.tokenizer.lexer = this, this.inlineQueue = [], this.state = { inLink: false, inRawBlock: false, linkEmitted: false, top: true };
|
|
12617
12905
|
let t = { other: m, block: H.normal, inline: B.normal };
|
|
12618
12906
|
this.options.pedantic ? (t.block = H.pedantic, t.inline = B.pedantic) : this.options.gfm && (t.block = H.gfm, this.options.breaks ? t.inline = B.breaks : t.inline = B.gfm), this.tokenizer.rules = t;
|
|
12619
12907
|
}
|
|
@@ -12621,10 +12909,10 @@ var x = class l {
|
|
|
12621
12909
|
return { block: H, inline: B };
|
|
12622
12910
|
}
|
|
12623
12911
|
static lex(e, t) {
|
|
12624
|
-
return new
|
|
12912
|
+
return new u(t).lex(e);
|
|
12625
12913
|
}
|
|
12626
12914
|
static lexInline(e, t) {
|
|
12627
|
-
return new
|
|
12915
|
+
return new u(t).inlineTokens(e);
|
|
12628
12916
|
}
|
|
12629
12917
|
lex(e) {
|
|
12630
12918
|
e = e.replace(m.carriageReturn, `
|
|
@@ -12645,21 +12933,21 @@ var x = class l {
|
|
|
12645
12933
|
break;
|
|
12646
12934
|
}
|
|
12647
12935
|
let r;
|
|
12648
|
-
if (this.options.extensions?.block?.some((
|
|
12936
|
+
if (this.options.extensions?.block?.some((i) => (r = i.call({ lexer: this }, e, t)) ? (e = e.substring(r.raw.length), t.push(r), true) : false)) continue;
|
|
12649
12937
|
if (r = this.tokenizer.space(e)) {
|
|
12650
12938
|
e = e.substring(r.raw.length);
|
|
12651
|
-
let
|
|
12652
|
-
r.raw.length === 1 &&
|
|
12939
|
+
let i = t.at(-1);
|
|
12940
|
+
r.raw.length === 1 && i !== void 0 ? i.raw += `
|
|
12653
12941
|
` : t.push(r);
|
|
12654
12942
|
continue;
|
|
12655
12943
|
}
|
|
12656
12944
|
if (r = this.tokenizer.code(e)) {
|
|
12657
12945
|
e = e.substring(r.raw.length);
|
|
12658
|
-
let
|
|
12659
|
-
|
|
12946
|
+
let i = t.at(-1);
|
|
12947
|
+
i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
|
|
12660
12948
|
`) ? "" : `
|
|
12661
|
-
`) + r.raw,
|
|
12662
|
-
` + r.text, this.inlineQueue.at(-1).src =
|
|
12949
|
+
`) + r.raw, i.text += `
|
|
12950
|
+
` + r.text, this.inlineQueue.at(-1).src = i.text) : t.push(r);
|
|
12663
12951
|
continue;
|
|
12664
12952
|
}
|
|
12665
12953
|
if (r = this.tokenizer.fences(e)) {
|
|
@@ -12688,11 +12976,11 @@ var x = class l {
|
|
|
12688
12976
|
}
|
|
12689
12977
|
if (r = this.tokenizer.def(e)) {
|
|
12690
12978
|
e = e.substring(r.raw.length);
|
|
12691
|
-
let
|
|
12692
|
-
|
|
12979
|
+
let i = t.at(-1);
|
|
12980
|
+
i?.type === "paragraph" || i?.type === "text" ? (i.raw += (i.raw.endsWith(`
|
|
12693
12981
|
`) ? "" : `
|
|
12694
|
-
`) + r.raw,
|
|
12695
|
-
` + r.raw, this.inlineQueue.at(-1).src =
|
|
12982
|
+
`) + r.raw, i.text += `
|
|
12983
|
+
` + r.raw, this.inlineQueue.at(-1).src = i.text) : this.tokens.links[r.tag] || (this.tokens.links[r.tag] = { href: r.href, title: r.title }, t.push(r));
|
|
12696
12984
|
continue;
|
|
12697
12985
|
}
|
|
12698
12986
|
if (r = this.tokenizer.table(e)) {
|
|
@@ -12703,28 +12991,28 @@ var x = class l {
|
|
|
12703
12991
|
e = e.substring(r.raw.length), t.push(r);
|
|
12704
12992
|
continue;
|
|
12705
12993
|
}
|
|
12706
|
-
let
|
|
12994
|
+
let o = e;
|
|
12707
12995
|
if (this.options.extensions?.startBlock) {
|
|
12708
|
-
let
|
|
12996
|
+
let i = 1 / 0, l = e.slice(1), a;
|
|
12709
12997
|
this.options.extensions.startBlock.forEach((p) => {
|
|
12710
|
-
a = p.call({ lexer: this },
|
|
12711
|
-
}),
|
|
12998
|
+
a = p.call({ lexer: this }, l), typeof a == "number" && a >= 0 && (i = Math.min(i, a));
|
|
12999
|
+
}), i < 1 / 0 && i >= 0 && (o = e.substring(0, i + 1));
|
|
12712
13000
|
}
|
|
12713
|
-
if (this.state.top && (r = this.tokenizer.paragraph(
|
|
12714
|
-
let
|
|
12715
|
-
n &&
|
|
13001
|
+
if (this.state.top && (r = this.tokenizer.paragraph(o))) {
|
|
13002
|
+
let i = t.at(-1);
|
|
13003
|
+
n && i?.type === "paragraph" ? (i.raw += (i.raw.endsWith(`
|
|
12716
13004
|
`) ? "" : `
|
|
12717
|
-
`) + r.raw,
|
|
12718
|
-
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src =
|
|
13005
|
+
`) + r.raw, i.text += `
|
|
13006
|
+
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r), n = o.length !== e.length, e = e.substring(r.raw.length);
|
|
12719
13007
|
continue;
|
|
12720
13008
|
}
|
|
12721
13009
|
if (r = this.tokenizer.text(e)) {
|
|
12722
13010
|
e = e.substring(r.raw.length);
|
|
12723
|
-
let
|
|
12724
|
-
|
|
13011
|
+
let i = t.at(-1);
|
|
13012
|
+
i?.type === "text" ? (i.raw += (i.raw.endsWith(`
|
|
12725
13013
|
`) ? "" : `
|
|
12726
|
-
`) + r.raw,
|
|
12727
|
-
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src =
|
|
13014
|
+
`) + r.raw, i.text += `
|
|
13015
|
+
` + r.text, this.inlineQueue.pop(), this.inlineQueue.at(-1).src = i.text) : t.push(r);
|
|
12728
13016
|
continue;
|
|
12729
13017
|
}
|
|
12730
13018
|
if (e) {
|
|
@@ -12751,84 +13039,84 @@ var x = class l {
|
|
|
12751
13039
|
this.tokenizer.lexer = this;
|
|
12752
13040
|
let n = e;
|
|
12753
13041
|
if (this.tokens.links && e.includes("[")) {
|
|
12754
|
-
let
|
|
13042
|
+
let i = this.tokenizer.rules.inline.reflinkSearch, l = (a) => {
|
|
12755
13043
|
let p = a.lastIndexOf("[");
|
|
12756
13044
|
if (!Object.hasOwn(this.tokens.links, a.slice(p + 1, -1))) return a;
|
|
12757
13045
|
if (p > 1 && a.charAt(0) !== "!") {
|
|
12758
13046
|
let c = a.slice(1, p - 1);
|
|
12759
|
-
if (this.linkInText(c)) return "[" + c.replace(
|
|
13047
|
+
if (this.linkInText(c)) return "[" + c.replace(i, l) + "][" + "a".repeat(a.length - p - 2) + "]";
|
|
12760
13048
|
}
|
|
12761
13049
|
return "[" + "a".repeat(a.length - 2) + "]";
|
|
12762
13050
|
};
|
|
12763
|
-
n = n.replace(
|
|
13051
|
+
n = n.replace(i, l);
|
|
12764
13052
|
}
|
|
12765
|
-
n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (
|
|
13053
|
+
n = n.replace(this.tokenizer.rules.inline.anyPunctuation, (i) => "+".repeat(i.length)), n = n.replace(this.tokenizer.rules.inline.blockSkip, (i, l, a) => {
|
|
12766
13054
|
let p = a ? a.length : 0;
|
|
12767
|
-
return
|
|
13055
|
+
return i.slice(0, p) + "[" + "a".repeat(i.length - p - 2) + "]";
|
|
12768
13056
|
}), n = this.options.hooks?.emStrongMask?.call({ lexer: this }, n) ?? n;
|
|
12769
|
-
let s = false, r = "",
|
|
13057
|
+
let s = false, r = "", o = 1 / 0;
|
|
12770
13058
|
for (; e; ) {
|
|
12771
|
-
if (e.length <
|
|
13059
|
+
if (e.length < o) o = e.length;
|
|
12772
13060
|
else {
|
|
12773
13061
|
this.infiniteLoopError(e.charCodeAt(0));
|
|
12774
13062
|
break;
|
|
12775
13063
|
}
|
|
12776
13064
|
s || (r = ""), s = false;
|
|
12777
|
-
let
|
|
12778
|
-
if (this.options.extensions?.inline?.some((a) => (
|
|
12779
|
-
if (
|
|
12780
|
-
e = e.substring(
|
|
13065
|
+
let i;
|
|
13066
|
+
if (this.options.extensions?.inline?.some((a) => (i = a.call({ lexer: this }, e, t)) ? (e = e.substring(i.raw.length), t.push(i), true) : false)) continue;
|
|
13067
|
+
if (i = this.tokenizer.escape(e)) {
|
|
13068
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12781
13069
|
continue;
|
|
12782
13070
|
}
|
|
12783
|
-
if (
|
|
12784
|
-
e = e.substring(
|
|
13071
|
+
if (i = this.tokenizer.tag(e)) {
|
|
13072
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12785
13073
|
continue;
|
|
12786
13074
|
}
|
|
12787
|
-
if (
|
|
12788
|
-
e = e.substring(
|
|
13075
|
+
if (i = this.tokenizer.link(e)) {
|
|
13076
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12789
13077
|
continue;
|
|
12790
13078
|
}
|
|
12791
|
-
if (
|
|
12792
|
-
e = e.substring(
|
|
13079
|
+
if (i = this.tokenizer.reflink(e, this.tokens.links)) {
|
|
13080
|
+
e = e.substring(i.raw.length);
|
|
12793
13081
|
let a = t.at(-1);
|
|
12794
|
-
|
|
13082
|
+
i.type === "text" && a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
|
|
12795
13083
|
continue;
|
|
12796
13084
|
}
|
|
12797
|
-
if (
|
|
12798
|
-
e = e.substring(
|
|
13085
|
+
if (i = this.tokenizer.emStrong(e, n, r)) {
|
|
13086
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12799
13087
|
continue;
|
|
12800
13088
|
}
|
|
12801
|
-
if (
|
|
12802
|
-
e = e.substring(
|
|
13089
|
+
if (i = this.tokenizer.codespan(e)) {
|
|
13090
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12803
13091
|
continue;
|
|
12804
13092
|
}
|
|
12805
|
-
if (
|
|
12806
|
-
e = e.substring(
|
|
13093
|
+
if (i = this.tokenizer.br(e)) {
|
|
13094
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12807
13095
|
continue;
|
|
12808
13096
|
}
|
|
12809
|
-
if (
|
|
12810
|
-
e = e.substring(
|
|
13097
|
+
if (i = this.tokenizer.del(e, n, r)) {
|
|
13098
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12811
13099
|
continue;
|
|
12812
13100
|
}
|
|
12813
|
-
if (
|
|
12814
|
-
e = e.substring(
|
|
13101
|
+
if (i = this.tokenizer.autolink(e)) {
|
|
13102
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12815
13103
|
continue;
|
|
12816
13104
|
}
|
|
12817
|
-
if (!this.state.inLink && (
|
|
12818
|
-
e = e.substring(
|
|
13105
|
+
if (!this.state.inLink && (i = this.tokenizer.url(e))) {
|
|
13106
|
+
e = e.substring(i.raw.length), t.push(i);
|
|
12819
13107
|
continue;
|
|
12820
13108
|
}
|
|
12821
|
-
let
|
|
13109
|
+
let l = e;
|
|
12822
13110
|
if (this.options.extensions?.startInline) {
|
|
12823
13111
|
let a = 1 / 0, p = e.slice(1), c;
|
|
12824
13112
|
this.options.extensions.startInline.forEach((h) => {
|
|
12825
13113
|
c = h.call({ lexer: this }, p), typeof c == "number" && c >= 0 && (a = Math.min(a, c));
|
|
12826
|
-
}), a < 1 / 0 && a >= 0 && (
|
|
13114
|
+
}), a < 1 / 0 && a >= 0 && (l = e.substring(0, a + 1));
|
|
12827
13115
|
}
|
|
12828
|
-
if (
|
|
12829
|
-
e = e.substring(
|
|
13116
|
+
if (i = this.tokenizer.inlineText(l)) {
|
|
13117
|
+
e = e.substring(i.raw.length), i.raw.slice(-1) !== "_" && (r = i.raw.slice(-1)), s = true;
|
|
12830
13118
|
let a = t.at(-1);
|
|
12831
|
-
a?.type === "text" ? (a.raw +=
|
|
13119
|
+
a?.type === "text" ? (a.raw += i.raw, a.text += i.text) : t.push(i);
|
|
12832
13120
|
continue;
|
|
12833
13121
|
}
|
|
12834
13122
|
if (e) {
|
|
@@ -12848,16 +13136,16 @@ var P = class {
|
|
|
12848
13136
|
options;
|
|
12849
13137
|
parser;
|
|
12850
13138
|
constructor(e) {
|
|
12851
|
-
this.options = e ||
|
|
13139
|
+
this.options = e || T;
|
|
12852
13140
|
}
|
|
12853
13141
|
space(e) {
|
|
12854
13142
|
return "";
|
|
12855
13143
|
}
|
|
12856
13144
|
code({ text: e, lang: t, escaped: n }) {
|
|
12857
|
-
let s = (t || "").match(m.notSpaceStart)?.[0], r = e.replace(m.endingNewline, "") + `
|
|
12858
|
-
|
|
12859
|
-
return s ? '<pre><code class="language-' +
|
|
12860
|
-
` : "<pre><code>" + (n ? r :
|
|
13145
|
+
let s = (t || "").match(m.notSpaceStart)?.[0], r = e ? e.replace(m.endingNewline, "") + `
|
|
13146
|
+
` : "";
|
|
13147
|
+
return s ? '<pre><code class="language-' + R(s) + '">' + (n ? r : R(r, true)) + `</code></pre>
|
|
13148
|
+
` : "<pre><code>" + (n ? r : R(r, true)) + `</code></pre>
|
|
12861
13149
|
`;
|
|
12862
13150
|
}
|
|
12863
13151
|
blockquote({ tokens: e }) {
|
|
@@ -12881,12 +13169,12 @@ ${this.parser.parse(e)}</blockquote>
|
|
|
12881
13169
|
}
|
|
12882
13170
|
list(e) {
|
|
12883
13171
|
let t = e.ordered, n = e.start, s = "";
|
|
12884
|
-
for (let
|
|
12885
|
-
let
|
|
12886
|
-
s += this.listitem(
|
|
13172
|
+
for (let i = 0; i < e.items.length; i++) {
|
|
13173
|
+
let l = e.items[i];
|
|
13174
|
+
s += this.listitem(l);
|
|
12887
13175
|
}
|
|
12888
|
-
let r = t ? "ol" : "ul",
|
|
12889
|
-
return "<" + r +
|
|
13176
|
+
let r = t ? "ol" : "ul", o = t && n !== 1 ? ' start="' + n + '"' : "";
|
|
13177
|
+
return "<" + r + o + `>
|
|
12890
13178
|
` + s + "</" + r + `>
|
|
12891
13179
|
`;
|
|
12892
13180
|
}
|
|
@@ -12907,9 +13195,9 @@ ${this.parser.parse(e)}</blockquote>
|
|
|
12907
13195
|
t += this.tablerow({ text: n });
|
|
12908
13196
|
let s = "";
|
|
12909
13197
|
for (let r = 0; r < e.rows.length; r++) {
|
|
12910
|
-
let
|
|
13198
|
+
let o = e.rows[r];
|
|
12911
13199
|
n = "";
|
|
12912
|
-
for (let
|
|
13200
|
+
for (let i = 0; i < o.length; i++) n += this.tablecell(o[i]);
|
|
12913
13201
|
s += this.tablerow({ text: n });
|
|
12914
13202
|
}
|
|
12915
13203
|
return s && (s = `<tbody>${s}</tbody>`), `<table>
|
|
@@ -12935,7 +13223,7 @@ ${e}</tr>
|
|
|
12935
13223
|
return `<em>${this.parser.parseInline(e)}</em>`;
|
|
12936
13224
|
}
|
|
12937
13225
|
codespan({ text: e }) {
|
|
12938
|
-
return `<code>${
|
|
13226
|
+
return `<code>${R(e, true)}</code>`;
|
|
12939
13227
|
}
|
|
12940
13228
|
br(e) {
|
|
12941
13229
|
return "<br>";
|
|
@@ -12943,23 +13231,23 @@ ${e}</tr>
|
|
|
12943
13231
|
del({ tokens: e }) {
|
|
12944
13232
|
return `<del>${this.parser.parseInline(e)}</del>`;
|
|
12945
13233
|
}
|
|
12946
|
-
link({ href: e, title: t,
|
|
12947
|
-
let
|
|
12948
|
-
if (
|
|
12949
|
-
e = r;
|
|
12950
|
-
let
|
|
12951
|
-
return t && (
|
|
13234
|
+
link({ href: e, title: t, text: n, tokens: s, autolink: r }) {
|
|
13235
|
+
let o = r ? R(n, true) : this.parser.parseInline(s), i = Y(e);
|
|
13236
|
+
if (i === null) return o;
|
|
13237
|
+
e = R(i, r);
|
|
13238
|
+
let l = '<a href="' + e + '"';
|
|
13239
|
+
return t && (l += ' title="' + R(t) + '"'), l += ">" + o + "</a>", l;
|
|
12952
13240
|
}
|
|
12953
13241
|
image({ href: e, title: t, text: n, tokens: s }) {
|
|
12954
13242
|
s && (n = this.parser.parseInline(s, this.parser.textRenderer));
|
|
12955
13243
|
let r = Y(e);
|
|
12956
|
-
if (r === null) return
|
|
13244
|
+
if (r === null) return R(n);
|
|
12957
13245
|
e = r;
|
|
12958
|
-
let
|
|
12959
|
-
return t && (
|
|
13246
|
+
let o = `<img src="${R(e)}" alt="${R(n)}"`;
|
|
13247
|
+
return t && (o += ` title="${R(t)}"`), o += ">", o;
|
|
12960
13248
|
}
|
|
12961
13249
|
text(e) {
|
|
12962
|
-
return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text :
|
|
13250
|
+
return "tokens" in e && e.tokens ? this.parser.parseInline(e.tokens) : "escaped" in e && e.escaped ? e.text : R(e.text);
|
|
12963
13251
|
}
|
|
12964
13252
|
};
|
|
12965
13253
|
var L = class {
|
|
@@ -12994,18 +13282,18 @@ var L = class {
|
|
|
12994
13282
|
return e;
|
|
12995
13283
|
}
|
|
12996
13284
|
};
|
|
12997
|
-
var b = class
|
|
13285
|
+
var b = class u2 {
|
|
12998
13286
|
options;
|
|
12999
13287
|
renderer;
|
|
13000
13288
|
textRenderer;
|
|
13001
13289
|
constructor(e) {
|
|
13002
|
-
this.options = e ||
|
|
13290
|
+
this.options = e || T, this.options.renderer = this.options.renderer || new P(), this.renderer = this.options.renderer, this.renderer.options = this.options, this.renderer.parser = this, this.textRenderer = new L();
|
|
13003
13291
|
}
|
|
13004
13292
|
static parse(e, t) {
|
|
13005
|
-
return new
|
|
13293
|
+
return new u2(t).parse(e);
|
|
13006
13294
|
}
|
|
13007
13295
|
static parseInline(e, t) {
|
|
13008
|
-
return new
|
|
13296
|
+
return new u2(t).parseInline(e);
|
|
13009
13297
|
}
|
|
13010
13298
|
parse(e) {
|
|
13011
13299
|
this.renderer.parser = this;
|
|
@@ -13013,9 +13301,9 @@ var b = class l2 {
|
|
|
13013
13301
|
for (let n = 0; n < e.length; n++) {
|
|
13014
13302
|
let s = e[n];
|
|
13015
13303
|
if (this.options.extensions?.renderers?.[s.type]) {
|
|
13016
|
-
let
|
|
13017
|
-
if (
|
|
13018
|
-
t +=
|
|
13304
|
+
let o = s, i = this.options.extensions.renderers[o.type].call({ parser: this }, o);
|
|
13305
|
+
if (i !== false || !["space", "hr", "heading", "code", "table", "blockquote", "list", "checkbox", "html", "def", "paragraph", "text"].includes(o.type)) {
|
|
13306
|
+
t += i || "";
|
|
13019
13307
|
continue;
|
|
13020
13308
|
}
|
|
13021
13309
|
}
|
|
@@ -13070,9 +13358,9 @@ var b = class l2 {
|
|
|
13070
13358
|
break;
|
|
13071
13359
|
}
|
|
13072
13360
|
default: {
|
|
13073
|
-
let
|
|
13074
|
-
if (this.options.silent) return console.error(
|
|
13075
|
-
throw new Error(
|
|
13361
|
+
let o = 'Token with "' + r.type + '" type was not found.';
|
|
13362
|
+
if (this.options.silent) return console.error(o), "";
|
|
13363
|
+
throw new Error(o);
|
|
13076
13364
|
}
|
|
13077
13365
|
}
|
|
13078
13366
|
}
|
|
@@ -13084,62 +13372,62 @@ var b = class l2 {
|
|
|
13084
13372
|
for (let s = 0; s < e.length; s++) {
|
|
13085
13373
|
let r = e[s];
|
|
13086
13374
|
if (this.options.extensions?.renderers?.[r.type]) {
|
|
13087
|
-
let
|
|
13088
|
-
if (
|
|
13089
|
-
n +=
|
|
13375
|
+
let i = this.options.extensions.renderers[r.type].call({ parser: this }, r);
|
|
13376
|
+
if (i !== false || !["escape", "html", "link", "image", "checkbox", "strong", "em", "codespan", "br", "del", "text"].includes(r.type)) {
|
|
13377
|
+
n += i || "";
|
|
13090
13378
|
continue;
|
|
13091
13379
|
}
|
|
13092
13380
|
}
|
|
13093
|
-
let
|
|
13094
|
-
switch (
|
|
13381
|
+
let o = r;
|
|
13382
|
+
switch (o.type) {
|
|
13095
13383
|
case "escape": {
|
|
13096
|
-
n += t.text(
|
|
13384
|
+
n += t.text(o);
|
|
13097
13385
|
break;
|
|
13098
13386
|
}
|
|
13099
13387
|
case "html": {
|
|
13100
|
-
n += t.html(
|
|
13388
|
+
n += t.html(o);
|
|
13101
13389
|
break;
|
|
13102
13390
|
}
|
|
13103
13391
|
case "link": {
|
|
13104
|
-
n += t.link(
|
|
13392
|
+
n += t.link(o);
|
|
13105
13393
|
break;
|
|
13106
13394
|
}
|
|
13107
13395
|
case "image": {
|
|
13108
|
-
n += t.image(
|
|
13396
|
+
n += t.image(o);
|
|
13109
13397
|
break;
|
|
13110
13398
|
}
|
|
13111
13399
|
case "checkbox": {
|
|
13112
|
-
n += t.checkbox(
|
|
13400
|
+
n += t.checkbox(o);
|
|
13113
13401
|
break;
|
|
13114
13402
|
}
|
|
13115
13403
|
case "strong": {
|
|
13116
|
-
n += t.strong(
|
|
13404
|
+
n += t.strong(o);
|
|
13117
13405
|
break;
|
|
13118
13406
|
}
|
|
13119
13407
|
case "em": {
|
|
13120
|
-
n += t.em(
|
|
13408
|
+
n += t.em(o);
|
|
13121
13409
|
break;
|
|
13122
13410
|
}
|
|
13123
13411
|
case "codespan": {
|
|
13124
|
-
n += t.codespan(
|
|
13412
|
+
n += t.codespan(o);
|
|
13125
13413
|
break;
|
|
13126
13414
|
}
|
|
13127
13415
|
case "br": {
|
|
13128
|
-
n += t.br(
|
|
13416
|
+
n += t.br(o);
|
|
13129
13417
|
break;
|
|
13130
13418
|
}
|
|
13131
13419
|
case "del": {
|
|
13132
|
-
n += t.del(
|
|
13420
|
+
n += t.del(o);
|
|
13133
13421
|
break;
|
|
13134
13422
|
}
|
|
13135
13423
|
case "text": {
|
|
13136
|
-
n += t.text(
|
|
13424
|
+
n += t.text(o);
|
|
13137
13425
|
break;
|
|
13138
13426
|
}
|
|
13139
13427
|
default: {
|
|
13140
|
-
let
|
|
13141
|
-
if (this.options.silent) return console.error(
|
|
13142
|
-
throw new Error(
|
|
13428
|
+
let i = 'Token with "' + o.type + '" type was not found.';
|
|
13429
|
+
if (this.options.silent) return console.error(i), "";
|
|
13430
|
+
throw new Error(i);
|
|
13143
13431
|
}
|
|
13144
13432
|
}
|
|
13145
13433
|
}
|
|
@@ -13150,7 +13438,7 @@ var S = class {
|
|
|
13150
13438
|
options;
|
|
13151
13439
|
block;
|
|
13152
13440
|
constructor(e) {
|
|
13153
|
-
this.options = e ||
|
|
13441
|
+
this.options = e || T;
|
|
13154
13442
|
}
|
|
13155
13443
|
static passThroughHooks = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens", "emStrongMask"]);
|
|
13156
13444
|
static passThroughHooksRespectAsync = /* @__PURE__ */ new Set(["preprocess", "postprocess", "processAllTokens"]);
|
|
@@ -13192,8 +13480,8 @@ var Z = class {
|
|
|
13192
13480
|
for (let s of e) switch (n = n.concat(t.call(this, s)), s.type) {
|
|
13193
13481
|
case "table": {
|
|
13194
13482
|
let r = s;
|
|
13195
|
-
for (let
|
|
13196
|
-
for (let
|
|
13483
|
+
for (let o of r.header) n = n.concat(this.walkTokens(o.tokens, t));
|
|
13484
|
+
for (let o of r.rows) for (let i of o) n = n.concat(this.walkTokens(i.tokens, t));
|
|
13197
13485
|
break;
|
|
13198
13486
|
}
|
|
13199
13487
|
case "list": {
|
|
@@ -13203,9 +13491,9 @@ var Z = class {
|
|
|
13203
13491
|
}
|
|
13204
13492
|
default: {
|
|
13205
13493
|
let r = s;
|
|
13206
|
-
this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((
|
|
13207
|
-
let
|
|
13208
|
-
n = n.concat(this.walkTokens(
|
|
13494
|
+
this.defaults.extensions?.childTokens?.[r.type] ? this.defaults.extensions.childTokens[r.type].forEach((o) => {
|
|
13495
|
+
let i = r[o].flat(1 / 0);
|
|
13496
|
+
n = n.concat(this.walkTokens(i, t));
|
|
13209
13497
|
}) : r.tokens && (n = n.concat(this.walkTokens(r.tokens, t)));
|
|
13210
13498
|
}
|
|
13211
13499
|
}
|
|
@@ -13218,26 +13506,26 @@ var Z = class {
|
|
|
13218
13506
|
if (s.async = this.defaults.async || s.async || false, n.extensions && (n.extensions.forEach((r) => {
|
|
13219
13507
|
if (!r.name) throw new Error("extension name required");
|
|
13220
13508
|
if ("renderer" in r) {
|
|
13221
|
-
let
|
|
13222
|
-
|
|
13223
|
-
let
|
|
13224
|
-
return
|
|
13509
|
+
let o = t.renderers[r.name];
|
|
13510
|
+
o ? t.renderers[r.name] = function(...i) {
|
|
13511
|
+
let l = r.renderer.apply(this, i);
|
|
13512
|
+
return l === false && (l = o.apply(this, i)), l;
|
|
13225
13513
|
} : t.renderers[r.name] = r.renderer;
|
|
13226
13514
|
}
|
|
13227
13515
|
if ("tokenizer" in r) {
|
|
13228
13516
|
if (!r.level || r.level !== "block" && r.level !== "inline") throw new Error("extension level must be 'block' or 'inline'");
|
|
13229
|
-
let
|
|
13230
|
-
|
|
13517
|
+
let o = t[r.level];
|
|
13518
|
+
o ? o.unshift(r.tokenizer) : t[r.level] = [r.tokenizer], r.start && (r.level === "block" ? t.startBlock ? t.startBlock.push(r.start) : t.startBlock = [r.start] : r.level === "inline" && (t.startInline ? t.startInline.push(r.start) : t.startInline = [r.start]));
|
|
13231
13519
|
}
|
|
13232
13520
|
"childTokens" in r && r.childTokens && (t.childTokens[r.name] = r.childTokens);
|
|
13233
13521
|
}), s.extensions = t), n.renderer) {
|
|
13234
13522
|
let r = this.defaults.renderer || new P(this.defaults);
|
|
13235
|
-
for (let
|
|
13236
|
-
if (!(
|
|
13237
|
-
if (["options", "parser"].includes(
|
|
13238
|
-
let
|
|
13239
|
-
r[
|
|
13240
|
-
let c =
|
|
13523
|
+
for (let o in n.renderer) {
|
|
13524
|
+
if (!(o in r)) throw new Error(`renderer '${o}' does not exist`);
|
|
13525
|
+
if (["options", "parser"].includes(o)) continue;
|
|
13526
|
+
let i = o, l = n.renderer[i], a = r[i];
|
|
13527
|
+
r[i] = (...p) => {
|
|
13528
|
+
let c = l.apply(r, p);
|
|
13241
13529
|
return c === false && (c = a.apply(r, p)), c || "";
|
|
13242
13530
|
};
|
|
13243
13531
|
}
|
|
@@ -13245,12 +13533,12 @@ var Z = class {
|
|
|
13245
13533
|
}
|
|
13246
13534
|
if (n.tokenizer) {
|
|
13247
13535
|
let r = this.defaults.tokenizer || new y(this.defaults);
|
|
13248
|
-
for (let
|
|
13249
|
-
if (!(
|
|
13250
|
-
if (["options", "rules", "lexer"].includes(
|
|
13251
|
-
let
|
|
13252
|
-
r[
|
|
13253
|
-
let c =
|
|
13536
|
+
for (let o in n.tokenizer) {
|
|
13537
|
+
if (!(o in r)) throw new Error(`tokenizer '${o}' does not exist`);
|
|
13538
|
+
if (["options", "rules", "lexer"].includes(o)) continue;
|
|
13539
|
+
let i = o, l = n.tokenizer[i], a = r[i];
|
|
13540
|
+
r[i] = (...p) => {
|
|
13541
|
+
let c = l.apply(r, p);
|
|
13254
13542
|
return c === false && (c = a.apply(r, p)), c;
|
|
13255
13543
|
};
|
|
13256
13544
|
}
|
|
@@ -13258,33 +13546,33 @@ var Z = class {
|
|
|
13258
13546
|
}
|
|
13259
13547
|
if (n.hooks) {
|
|
13260
13548
|
let r = this.defaults.hooks || new S();
|
|
13261
|
-
for (let
|
|
13262
|
-
if (!(
|
|
13263
|
-
if (["options", "block"].includes(
|
|
13264
|
-
let
|
|
13265
|
-
S.passThroughHooks.has(
|
|
13266
|
-
if (this.defaults.async && S.passThroughHooksRespectAsync.has(
|
|
13267
|
-
let h = await
|
|
13549
|
+
for (let o in n.hooks) {
|
|
13550
|
+
if (!(o in r)) throw new Error(`hook '${o}' does not exist`);
|
|
13551
|
+
if (["options", "block"].includes(o)) continue;
|
|
13552
|
+
let i = o, l = n.hooks[i], a = r[i];
|
|
13553
|
+
S.passThroughHooks.has(o) ? r[i] = (p) => {
|
|
13554
|
+
if (this.defaults.async && S.passThroughHooksRespectAsync.has(o)) return (async () => {
|
|
13555
|
+
let h = await l.call(r, p);
|
|
13268
13556
|
return a.call(r, h);
|
|
13269
13557
|
})();
|
|
13270
|
-
let c =
|
|
13558
|
+
let c = l.call(r, p);
|
|
13271
13559
|
return a.call(r, c);
|
|
13272
|
-
} : r[
|
|
13560
|
+
} : r[i] = (...p) => {
|
|
13273
13561
|
if (this.defaults.async) return (async () => {
|
|
13274
|
-
let h = await
|
|
13562
|
+
let h = await l.apply(r, p);
|
|
13275
13563
|
return h === false && (h = await a.apply(r, p)), h;
|
|
13276
13564
|
})();
|
|
13277
|
-
let c =
|
|
13565
|
+
let c = l.apply(r, p);
|
|
13278
13566
|
return c === false && (c = a.apply(r, p)), c;
|
|
13279
13567
|
};
|
|
13280
13568
|
}
|
|
13281
13569
|
s.hooks = r;
|
|
13282
13570
|
}
|
|
13283
13571
|
if (n.walkTokens) {
|
|
13284
|
-
let r = this.defaults.walkTokens,
|
|
13285
|
-
s.walkTokens = function(
|
|
13286
|
-
let
|
|
13287
|
-
return
|
|
13572
|
+
let r = this.defaults.walkTokens, o = n.walkTokens;
|
|
13573
|
+
s.walkTokens = function(i) {
|
|
13574
|
+
let l = [];
|
|
13575
|
+
return l.push(o.call(this, i)), r && (l = l.concat(r.call(this, i))), l;
|
|
13288
13576
|
};
|
|
13289
13577
|
}
|
|
13290
13578
|
this.defaults = { ...this.defaults, ...s };
|
|
@@ -13301,24 +13589,24 @@ var Z = class {
|
|
|
13301
13589
|
}
|
|
13302
13590
|
parseMarkdown(e) {
|
|
13303
13591
|
return (n, s) => {
|
|
13304
|
-
let r = { ...s },
|
|
13305
|
-
if (this.defaults.async === true && r.async === false) return
|
|
13306
|
-
if (typeof n > "u" || n === null) return
|
|
13307
|
-
if (typeof n != "string") return
|
|
13308
|
-
if (
|
|
13309
|
-
let
|
|
13310
|
-
|
|
13311
|
-
let d = await (
|
|
13312
|
-
return
|
|
13313
|
-
})().catch(
|
|
13592
|
+
let r = { ...s }, o = { ...this.defaults, ...r }, i = this.onError(!!o.silent, !!o.async);
|
|
13593
|
+
if (this.defaults.async === true && r.async === false) return i(new Error("marked(): The async option was set to true by an extension. Remove async: false from the parse options object to return a Promise."));
|
|
13594
|
+
if (typeof n > "u" || n === null) return i(new Error("marked(): input parameter is undefined or null"));
|
|
13595
|
+
if (typeof n != "string") return i(new Error("marked(): input parameter is of type " + Object.prototype.toString.call(n) + ", string expected"));
|
|
13596
|
+
if (o.hooks && (o.hooks.options = o, o.hooks.block = e), o.async) return (async () => {
|
|
13597
|
+
let l = o.hooks ? await o.hooks.preprocess(n) : n, p = await (o.hooks ? await o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(l, o), c = o.hooks ? await o.hooks.processAllTokens(p) : p;
|
|
13598
|
+
o.walkTokens && await Promise.all(this.walkTokens(c, o.walkTokens));
|
|
13599
|
+
let d = await (o.hooks ? await o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(c, o);
|
|
13600
|
+
return o.hooks ? await o.hooks.postprocess(d) : d;
|
|
13601
|
+
})().catch(i);
|
|
13314
13602
|
try {
|
|
13315
|
-
|
|
13316
|
-
let a = (
|
|
13317
|
-
|
|
13318
|
-
let c = (
|
|
13319
|
-
return
|
|
13320
|
-
} catch (
|
|
13321
|
-
return
|
|
13603
|
+
o.hooks && (n = o.hooks.preprocess(n));
|
|
13604
|
+
let a = (o.hooks ? o.hooks.provideLexer(e) : e ? x.lex : x.lexInline)(n, o);
|
|
13605
|
+
o.hooks && (a = o.hooks.processAllTokens(a)), o.walkTokens && this.walkTokens(a, o.walkTokens);
|
|
13606
|
+
let c = (o.hooks ? o.hooks.provideParser(e) : e ? b.parse : b.parseInline)(a, o);
|
|
13607
|
+
return o.hooks && (c = o.hooks.postprocess(c)), c;
|
|
13608
|
+
} catch (l) {
|
|
13609
|
+
return i(l);
|
|
13322
13610
|
}
|
|
13323
13611
|
};
|
|
13324
13612
|
}
|
|
@@ -13326,7 +13614,7 @@ var Z = class {
|
|
|
13326
13614
|
return (n) => {
|
|
13327
13615
|
if (n.message += `
|
|
13328
13616
|
Please report this to https://github.com/markedjs/marked.`, e) {
|
|
13329
|
-
let s = "<p>An error occurred:</p><pre>" +
|
|
13617
|
+
let s = "<p>An error occurred:</p><pre>" + R(n.message + "", true) + "</pre>";
|
|
13330
13618
|
return t ? Promise.resolve(s) : s;
|
|
13331
13619
|
}
|
|
13332
13620
|
if (t) return Promise.reject(n);
|
|
@@ -13335,20 +13623,20 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
13335
13623
|
}
|
|
13336
13624
|
};
|
|
13337
13625
|
var M = new Z();
|
|
13338
|
-
function f(
|
|
13339
|
-
return M.parse(
|
|
13626
|
+
function f(u3, e) {
|
|
13627
|
+
return M.parse(u3, e);
|
|
13340
13628
|
}
|
|
13341
|
-
f.options = f.setOptions = function(
|
|
13342
|
-
return M.setOptions(
|
|
13629
|
+
f.options = f.setOptions = function(u3) {
|
|
13630
|
+
return M.setOptions(u3), f.defaults = M.defaults, j(f.defaults), f;
|
|
13343
13631
|
};
|
|
13344
13632
|
f.getDefaults = A;
|
|
13345
|
-
f.defaults =
|
|
13346
|
-
function
|
|
13347
|
-
return M.use(...
|
|
13633
|
+
f.defaults = T;
|
|
13634
|
+
function gt(...u3) {
|
|
13635
|
+
return M.use(...u3), f.defaults = M.defaults, j(f.defaults), f;
|
|
13348
13636
|
}
|
|
13349
|
-
f.use =
|
|
13350
|
-
f.walkTokens = function(
|
|
13351
|
-
return M.walkTokens(
|
|
13637
|
+
f.use = gt;
|
|
13638
|
+
f.walkTokens = function(u3, e) {
|
|
13639
|
+
return M.walkTokens(u3, e);
|
|
13352
13640
|
};
|
|
13353
13641
|
f.parseInline = M.parseInline;
|
|
13354
13642
|
f.Parser = b;
|
|
@@ -13360,12 +13648,12 @@ f.lexer = x.lex;
|
|
|
13360
13648
|
f.Tokenizer = y;
|
|
13361
13649
|
f.Hooks = S;
|
|
13362
13650
|
f.parse = f;
|
|
13363
|
-
var
|
|
13364
|
-
var
|
|
13365
|
-
var
|
|
13366
|
-
var
|
|
13367
|
-
var
|
|
13368
|
-
var
|
|
13651
|
+
var rn = f.options;
|
|
13652
|
+
var sn = f.setOptions;
|
|
13653
|
+
var on = f.walkTokens;
|
|
13654
|
+
var an = f.parseInline;
|
|
13655
|
+
var un = b.parse;
|
|
13656
|
+
var pn = x.lex;
|
|
13369
13657
|
|
|
13370
13658
|
// src/ui/transcript/render_markdown.ts
|
|
13371
13659
|
var parser = new Z({ gfm: true, breaks: true });
|
|
@@ -13846,12 +14134,17 @@ var Transcript = class {
|
|
|
13846
14134
|
/**
|
|
13847
14135
|
* Start following the foot of the list, and wire the jump button to it.
|
|
13848
14136
|
* Called while rendering rather than at construction: the viewport has to
|
|
13849
|
-
* exist and the observer has to have something to observe.
|
|
14137
|
+
* exist and the observer has to have something to observe. The button
|
|
14138
|
+
* outlives a connection, so its listener goes under `signal`.
|
|
13850
14139
|
*/
|
|
13851
|
-
mountScroller(jumpButton) {
|
|
13852
|
-
jumpButton.addEventListener(
|
|
13853
|
-
|
|
13854
|
-
|
|
14140
|
+
mountScroller(jumpButton, signal) {
|
|
14141
|
+
jumpButton.addEventListener(
|
|
14142
|
+
"click",
|
|
14143
|
+
() => {
|
|
14144
|
+
this.jump();
|
|
14145
|
+
},
|
|
14146
|
+
{ signal }
|
|
14147
|
+
);
|
|
13855
14148
|
this.#scroller = createStickToBottom({
|
|
13856
14149
|
viewport: this.#host.messages,
|
|
13857
14150
|
onMissedContent: (missed) => {
|
|
@@ -14238,6 +14531,9 @@ import {
|
|
|
14238
14531
|
buildResumeArray,
|
|
14239
14532
|
randomUUID as randomUUID4
|
|
14240
14533
|
} from "@ag-ui/client";
|
|
14534
|
+
import {
|
|
14535
|
+
contentToText as contentToText2
|
|
14536
|
+
} from "@ag-ui/core";
|
|
14241
14537
|
var ConnectionLostError = class extends Error {
|
|
14242
14538
|
constructor(message) {
|
|
14243
14539
|
super(message);
|
|
@@ -14258,29 +14554,6 @@ var AgUiClient = class {
|
|
|
14258
14554
|
* set would miss entirely.
|
|
14259
14555
|
*/
|
|
14260
14556
|
#closedMessageIds = /* @__PURE__ */ new Set();
|
|
14261
|
-
/**
|
|
14262
|
-
* How each tool call ended, keyed by call id, for the transcript this client
|
|
14263
|
-
* persists.
|
|
14264
|
-
*
|
|
14265
|
-
* A side table rather than a field written onto the message, because neither
|
|
14266
|
-
* producer of a tool message will carry it. `@ag-ui/client` builds the
|
|
14267
|
-
* server-side one by destructuring five named fields off the event, so an
|
|
14268
|
-
* `outcome` beside them is dropped before the message exists; and writing it
|
|
14269
|
-
* back onto that message afterwards would put it in `agent.messages`, which is
|
|
14270
|
-
* what the *next* request sends to the server. This keeps the annotation on
|
|
14271
|
-
* the copy handed to the store and off the wire.
|
|
14272
|
-
*
|
|
14273
|
-
* Per client, not per run: `saveMessages` rewrites the whole transcript on
|
|
14274
|
-
* every persist, so an outcome recorded in round one has to still be here in
|
|
14275
|
-
* round five or the earlier card silently reverts to a green one. Bounded by
|
|
14276
|
-
* the number of tool calls in the conversation, which the transcript beside it
|
|
14277
|
-
* already is.
|
|
14278
|
-
*
|
|
14279
|
-
* Values are `unknown` because a restored seed fills it too (see
|
|
14280
|
-
* {@link #adoptSeededOutcomes}), and a store is not trusted to hold only the
|
|
14281
|
-
* words this class writes: whatever it held is written back as it was.
|
|
14282
|
-
*/
|
|
14283
|
-
#outcomes = /* @__PURE__ */ new Map();
|
|
14284
14557
|
#connectionLostMessage;
|
|
14285
14558
|
#unfinishedMessage;
|
|
14286
14559
|
#declinedMessage;
|
|
@@ -14302,7 +14575,7 @@ var AgUiClient = class {
|
|
|
14302
14575
|
this.#declinedMessage = config.declinedMessage ?? "User declined the action.";
|
|
14303
14576
|
const rounds = config.maxToolRounds ?? MAX_TOOL_ROUNDS;
|
|
14304
14577
|
this.#maxToolRounds = rounds >= 1 ? Math.floor(rounds) : MAX_TOOL_ROUNDS;
|
|
14305
|
-
this.#
|
|
14578
|
+
this.#moveSeededKeysIntoMetadata();
|
|
14306
14579
|
const onStateChanged = config.onStateChanged;
|
|
14307
14580
|
if (onStateChanged !== void 0) {
|
|
14308
14581
|
this.#agent.subscribe({
|
|
@@ -14336,15 +14609,18 @@ var AgUiClient = class {
|
|
|
14336
14609
|
* tools (bounded by {@link AgUiClientConfig.maxToolRounds}, which defaults to
|
|
14337
14610
|
* {@link MAX_TOOL_ROUNDS}).
|
|
14338
14611
|
*
|
|
14339
|
-
* `attachments` ride
|
|
14340
|
-
*
|
|
14612
|
+
* `attachments` ride in the user message's `metadata`, under
|
|
14613
|
+
* `attachments`, which is how the server learns which files the agent can
|
|
14614
|
+
* read and how the default store round-trips them for history replay; see
|
|
14341
14615
|
* {@link messageAttachments}.
|
|
14342
14616
|
*/
|
|
14343
14617
|
async send(content, attachments = []) {
|
|
14344
|
-
const message = {
|
|
14345
|
-
|
|
14346
|
-
|
|
14347
|
-
|
|
14618
|
+
const message = {
|
|
14619
|
+
id: randomUUID4(),
|
|
14620
|
+
role: "user",
|
|
14621
|
+
content,
|
|
14622
|
+
...attachments.length > 0 ? { metadata: { attachments } } : {}
|
|
14623
|
+
};
|
|
14348
14624
|
this.#agent.addMessage(message);
|
|
14349
14625
|
this.#persist();
|
|
14350
14626
|
await this.#run();
|
|
@@ -14430,36 +14706,31 @@ var AgUiClient = class {
|
|
|
14430
14706
|
this.#handlers.onCancelled();
|
|
14431
14707
|
}
|
|
14432
14708
|
/**
|
|
14433
|
-
* Move the
|
|
14434
|
-
* messages
|
|
14709
|
+
* Move the keys a history stored by an earlier release carries at the top
|
|
14710
|
+
* level of its messages into their `metadata`, where this release writes them.
|
|
14435
14711
|
*
|
|
14436
|
-
*
|
|
14437
|
-
*
|
|
14438
|
-
*
|
|
14439
|
-
*
|
|
14440
|
-
*
|
|
14441
|
-
*
|
|
14712
|
+
* Earlier releases wrote a tool message's `outcome` and a user message's
|
|
14713
|
+
* `attachments` beside the protocol's own fields. `@ag-ui/client` 1.0 strips
|
|
14714
|
+
* every undeclared key from the input it sends, so a restored conversation
|
|
14715
|
+
* sent as it was stored would lose both on its first request: the server
|
|
14716
|
+
* would no longer be told about any file attached before the upgrade, and
|
|
14717
|
+
* each strip would print a warning. Moved rather than dropped, so the next
|
|
14718
|
+
* save writes the conversation in the shape this release reads first and a
|
|
14719
|
+
* reload after it still replays a declined card as declined.
|
|
14442
14720
|
*
|
|
14443
|
-
*
|
|
14444
|
-
*
|
|
14445
|
-
*
|
|
14446
|
-
*
|
|
14721
|
+
* Merged into the metadata a message already has, with a key already there
|
|
14722
|
+
* winning: a message carrying both was last written by the newer writer.
|
|
14723
|
+
* `ag_ui_chat_restored_outcome_wire.test.ts` reads the result off the body of
|
|
14724
|
+
* a real request. The check before `setMessages` only spares a copy when
|
|
14725
|
+
* nothing moves, which is every restore of a store this release wrote;
|
|
14726
|
+
* nothing observable depends on it.
|
|
14447
14727
|
*/
|
|
14448
|
-
#
|
|
14728
|
+
#moveSeededKeysIntoMetadata() {
|
|
14449
14729
|
const seeded = this.#agent.messages;
|
|
14450
|
-
|
|
14451
|
-
|
|
14730
|
+
const moved = seeded.map(withTopLevelKeysInMetadata);
|
|
14731
|
+
if (moved.some((message, index) => message !== seeded[index])) {
|
|
14732
|
+
this.#agent.setMessages(moved);
|
|
14452
14733
|
}
|
|
14453
|
-
this.#agent.setMessages(
|
|
14454
|
-
seeded.map((message) => {
|
|
14455
|
-
if (message.role !== "tool") {
|
|
14456
|
-
return message;
|
|
14457
|
-
}
|
|
14458
|
-
const { outcome, ...wire } = message;
|
|
14459
|
-
this.#outcomes.set(message.toolCallId, outcome);
|
|
14460
|
-
return wire;
|
|
14461
|
-
})
|
|
14462
|
-
);
|
|
14463
14734
|
}
|
|
14464
14735
|
/**
|
|
14465
14736
|
* Give every tool call in history a result, before a request carries it.
|
|
@@ -14476,17 +14747,21 @@ var AgUiClient = class {
|
|
|
14476
14747
|
* approval runs or denies them server-side, and a result here would answer
|
|
14477
14748
|
* them twice.
|
|
14478
14749
|
*
|
|
14479
|
-
* The
|
|
14480
|
-
*
|
|
14750
|
+
* The outcome rides in the result's `metadata`, where the client folds a
|
|
14751
|
+
* server's own, so the next request carries it and a reload replays it. A
|
|
14752
|
+
* server that does not read it ignores it: `metadata` is a declared field.
|
|
14481
14753
|
*/
|
|
14482
14754
|
#answerUnansweredCalls(resuming) {
|
|
14483
14755
|
const messages = this.#agent.messages;
|
|
14484
14756
|
const answered = answerUnansweredCalls(
|
|
14485
14757
|
messages,
|
|
14486
|
-
(toolCallId) => {
|
|
14487
|
-
|
|
14488
|
-
|
|
14489
|
-
|
|
14758
|
+
(toolCallId) => ({
|
|
14759
|
+
id: randomUUID4(),
|
|
14760
|
+
role: "tool",
|
|
14761
|
+
content: this.#unfinishedMessage,
|
|
14762
|
+
toolCallId,
|
|
14763
|
+
metadata: { outcome: TOOL_OUTCOME.INTERRUPTED }
|
|
14764
|
+
}),
|
|
14490
14765
|
resuming
|
|
14491
14766
|
);
|
|
14492
14767
|
if (answered !== messages) {
|
|
@@ -14513,40 +14788,43 @@ var AgUiClient = class {
|
|
|
14513
14788
|
for (const interrupt of interrupts) {
|
|
14514
14789
|
const toolCallId = interrupt.toolCallId;
|
|
14515
14790
|
if (toolCallId !== void 0 && responses[interrupt.id]?.status === "cancelled") {
|
|
14516
|
-
this.#outcomes.set(toolCallId, TOOL_OUTCOME.DENIED);
|
|
14517
14791
|
this.#agent.addMessage({
|
|
14518
14792
|
id: randomUUID4(),
|
|
14519
14793
|
role: "tool",
|
|
14520
14794
|
content: this.#declinedMessage,
|
|
14521
|
-
toolCallId
|
|
14795
|
+
toolCallId,
|
|
14796
|
+
metadata: { outcome: TOOL_OUTCOME.DENIED }
|
|
14522
14797
|
});
|
|
14523
14798
|
}
|
|
14524
14799
|
}
|
|
14525
14800
|
this.#persist();
|
|
14526
14801
|
}
|
|
14527
14802
|
/**
|
|
14528
|
-
* Hand the transcript to the host's store
|
|
14529
|
-
* knows about how each tool call ended.
|
|
14803
|
+
* Hand the transcript to the host's store.
|
|
14530
14804
|
*
|
|
14531
|
-
*
|
|
14532
|
-
*
|
|
14533
|
-
*
|
|
14805
|
+
* The list as the agent holds it, with nothing added: how each tool call
|
|
14806
|
+
* ended rides in its result's `metadata`, which the client folds in from a
|
|
14807
|
+
* server's `TOOL_CALL_RESULT` and this class writes for the results it makes
|
|
14808
|
+
* itself, so the store sees exactly what the next request sends.
|
|
14534
14809
|
*/
|
|
14535
14810
|
#persist() {
|
|
14536
|
-
|
|
14537
|
-
|
|
14538
|
-
|
|
14539
|
-
|
|
14540
|
-
|
|
14541
|
-
|
|
14542
|
-
|
|
14543
|
-
|
|
14544
|
-
|
|
14545
|
-
|
|
14546
|
-
|
|
14547
|
-
|
|
14548
|
-
|
|
14549
|
-
|
|
14811
|
+
this.#onPersist(this.#agent.messages);
|
|
14812
|
+
}
|
|
14813
|
+
/**
|
|
14814
|
+
* The history in the form a save writes it, which is now {@link messages}
|
|
14815
|
+
* itself.
|
|
14816
|
+
*
|
|
14817
|
+
* It differed while this client kept how each tool call ended in a side table
|
|
14818
|
+
* and annotated a copy for the store, because `@ag-ui/client` 0.x kept nothing
|
|
14819
|
+
* but five named fields of a result. 1.0 folds a result's `metadata` onto the
|
|
14820
|
+
* message it appends, so the outcome is on the message and there is no copy
|
|
14821
|
+
* left to make.
|
|
14822
|
+
*
|
|
14823
|
+
* @deprecated Read {@link messages}. Kept so a caller written against the
|
|
14824
|
+
* getter keeps compiling and gets the same list.
|
|
14825
|
+
*/
|
|
14826
|
+
get annotatedMessages() {
|
|
14827
|
+
return this.messages;
|
|
14550
14828
|
}
|
|
14551
14829
|
async #runLoop() {
|
|
14552
14830
|
let resume;
|
|
@@ -14606,14 +14884,12 @@ var AgUiClient = class {
|
|
|
14606
14884
|
if (result.halt === true) {
|
|
14607
14885
|
return;
|
|
14608
14886
|
}
|
|
14609
|
-
if (result.outcome !== void 0) {
|
|
14610
|
-
this.#outcomes.set(call.id, result.outcome);
|
|
14611
|
-
}
|
|
14612
14887
|
this.#agent.addMessage({
|
|
14613
14888
|
id: randomUUID4(),
|
|
14614
14889
|
role: "tool",
|
|
14615
14890
|
content: result.content,
|
|
14616
|
-
toolCallId: call.id
|
|
14891
|
+
toolCallId: call.id,
|
|
14892
|
+
...result.outcome === void 0 ? {} : { metadata: { outcome: result.outcome } }
|
|
14617
14893
|
});
|
|
14618
14894
|
this.#persist();
|
|
14619
14895
|
executed = true;
|
|
@@ -14626,7 +14902,6 @@ var AgUiClient = class {
|
|
|
14626
14902
|
#buildSubscriber(pending, runState) {
|
|
14627
14903
|
const h = this.#handlers;
|
|
14628
14904
|
const closed = this.#closedMessageIds;
|
|
14629
|
-
const outcomes = this.#outcomes;
|
|
14630
14905
|
const cancelled = () => this.#cancelled;
|
|
14631
14906
|
const pendingDeltas = /* @__PURE__ */ new Set();
|
|
14632
14907
|
return {
|
|
@@ -14657,11 +14932,8 @@ var AgUiClient = class {
|
|
|
14657
14932
|
h.onToolCall(call);
|
|
14658
14933
|
},
|
|
14659
14934
|
onToolCallResultEvent({ event }) {
|
|
14660
|
-
const outcome = event["outcome"];
|
|
14661
|
-
|
|
14662
|
-
outcomes.set(event.toolCallId, outcome);
|
|
14663
|
-
}
|
|
14664
|
-
h.onToolResult(event.toolCallId, event.content, outcome);
|
|
14935
|
+
const outcome = event.metadata?.["outcome"];
|
|
14936
|
+
h.onToolResult(event.toolCallId, contentToText2(event.content), outcome);
|
|
14665
14937
|
},
|
|
14666
14938
|
onActivitySnapshotEvent({ event, messages }) {
|
|
14667
14939
|
const known = messages.some(
|
|
@@ -14719,9 +14991,11 @@ var AgUiClient = class {
|
|
|
14719
14991
|
}
|
|
14720
14992
|
pendingDeltas.clear();
|
|
14721
14993
|
},
|
|
14722
|
-
// `@ag-ui/client`
|
|
14723
|
-
//
|
|
14724
|
-
//
|
|
14994
|
+
// THINKING_* left the protocol in its 1.0, but `@ag-ui/client` still
|
|
14995
|
+
// converts a server's THINKING_* events onto these REASONING_* callbacks,
|
|
14996
|
+
// with a console warning, for a deprecation window it sets. Nothing in the
|
|
14997
|
+
// family emits THINKING_*: pydantic-ai has sent REASONING_* at every
|
|
14998
|
+
// protocol version django-ag-ui admits.
|
|
14725
14999
|
onReasoningStartEvent() {
|
|
14726
15000
|
h.onReasoningStart();
|
|
14727
15001
|
},
|
|
@@ -14768,6 +15042,22 @@ function isAbortError(error) {
|
|
|
14768
15042
|
}
|
|
14769
15043
|
return error.name === "AbortError" || error instanceof TypeError && /abort/i.test(error.message);
|
|
14770
15044
|
}
|
|
15045
|
+
function withTopLevelKeysInMetadata(message) {
|
|
15046
|
+
const { outcome, attachments, ...wire } = message;
|
|
15047
|
+
if (outcome === void 0 && attachments === void 0) {
|
|
15048
|
+
return message;
|
|
15049
|
+
}
|
|
15050
|
+
const existing = wire.metadata;
|
|
15051
|
+
return {
|
|
15052
|
+
...wire,
|
|
15053
|
+
metadata: {
|
|
15054
|
+
...outcome === void 0 ? {} : { outcome },
|
|
15055
|
+
...attachments === void 0 ? {} : { attachments },
|
|
15056
|
+
// `null` passes the check and spreads as nothing, which is what it means.
|
|
15057
|
+
...typeof existing === "object" ? existing : {}
|
|
15058
|
+
}
|
|
15059
|
+
};
|
|
15060
|
+
}
|
|
14771
15061
|
|
|
14772
15062
|
// src/core/conversation_store.ts
|
|
14773
15063
|
import { randomUUID as randomUUID5 } from "@ag-ui/client";
|
|
@@ -15771,6 +16061,8 @@ var AgUiChat = class extends HTMLElement {
|
|
|
15771
16061
|
* Optional full replacement for the `ask_user` question UI, resolving with
|
|
15772
16062
|
* the answer; the same seam as {@link approvalRenderer}, styled via `strings`
|
|
15773
16063
|
* and the `question*` `::part()`s when left unset. Requires {@link askUser}.
|
|
16064
|
+
* A renderer that throws or rejects hands the question to the built-in card,
|
|
16065
|
+
* as a failing {@link approvalRenderer} does, unless Stop already fired.
|
|
15774
16066
|
*/
|
|
15775
16067
|
askUserRenderer = null;
|
|
15776
16068
|
/**
|
|
@@ -16075,10 +16367,37 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16075
16367
|
#voice;
|
|
16076
16368
|
/** Whether the element is currently in the DOM; gates the connect-time warning. */
|
|
16077
16369
|
#connected = false;
|
|
16370
|
+
/**
|
|
16371
|
+
* Aborted when the element leaves the document, and replaced when it comes
|
|
16372
|
+
* back.
|
|
16373
|
+
*
|
|
16374
|
+
* Every listener connecting adds to an element that outlives the connection
|
|
16375
|
+
* -- the composer, Send, the launcher, the shell -- is added under this
|
|
16376
|
+
* signal. Connecting runs again on every insertion, so a listener added
|
|
16377
|
+
* without it is a second listener the next time: one click on Stop stopped
|
|
16378
|
+
* the run three times, and one press of the built-in theme toggle flipped it
|
|
16379
|
+
* twice, back to where it started.
|
|
16380
|
+
*/
|
|
16381
|
+
#connection = new AbortController();
|
|
16382
|
+
/**
|
|
16383
|
+
* Whether the element has connected before, which makes this connection a
|
|
16384
|
+
* re-insertion: there is a transcript on screen from last time, and the
|
|
16385
|
+
* history replay would draw the conversation a second time beneath it.
|
|
16386
|
+
*/
|
|
16387
|
+
#connectedBefore = false;
|
|
16388
|
+
/**
|
|
16389
|
+
* The remote store `data-threads-url` wrapped around the conversation store,
|
|
16390
|
+
* and the store inside it, so connecting again can wrap that store rather
|
|
16391
|
+
* than the wrapper.
|
|
16392
|
+
*/
|
|
16393
|
+
#threadStore = null;
|
|
16078
16394
|
#client = null;
|
|
16079
16395
|
// Seed for the next client. Once one exists it owns the live value (the
|
|
16080
16396
|
// agent applies STATE_SNAPSHOT / STATE_DELTA into it), so this is only the
|
|
16081
|
-
// starting point — `sharedState` reads through to the client when present
|
|
16397
|
+
// starting point — `sharedState` reads through to the client when present,
|
|
16398
|
+
// and to a running checkpoint continuation before that. Every client mirrors
|
|
16399
|
+
// its changes here, which is what the client built after a continuation is
|
|
16400
|
+
// seeded from.
|
|
16082
16401
|
#sharedState = {};
|
|
16083
16402
|
// Whether an interaction is in flight (first onRunStart → onSettled). Drives
|
|
16084
16403
|
// the Send⇄Stop button: `agent.isRunning` is false between frontend-tool
|
|
@@ -16285,7 +16604,9 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16285
16604
|
}
|
|
16286
16605
|
});
|
|
16287
16606
|
this.#checkpoints = new CheckpointMenu((runId, verb) => {
|
|
16288
|
-
void this.#history.continueRun(runId, verb)
|
|
16607
|
+
void this.#history.continueRun(runId, verb).catch((error) => {
|
|
16608
|
+
console.warn("<ag-ui-chat>: continuing a run failed", error);
|
|
16609
|
+
});
|
|
16289
16610
|
});
|
|
16290
16611
|
this.#history = new ConversationHistory({
|
|
16291
16612
|
element: this,
|
|
@@ -16305,8 +16626,14 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16305
16626
|
requestCredentials: () => this.#requestCredentials(),
|
|
16306
16627
|
appendMessage: (role, content) => this.appendMessage(role, content),
|
|
16307
16628
|
autoGrow: () => autoGrow(this.#input),
|
|
16629
|
+
continuationEnded: () => this.#flushQueued(),
|
|
16630
|
+
client: () => this.#client,
|
|
16308
16631
|
ensureClient: () => this.#ensureClient(),
|
|
16309
16632
|
buildClient: (seed) => this.#buildClient(seed),
|
|
16633
|
+
releaseClient: () => {
|
|
16634
|
+
this.#client = null;
|
|
16635
|
+
},
|
|
16636
|
+
running: () => this.#running,
|
|
16310
16637
|
cancelRun: () => this.#cancelRun(),
|
|
16311
16638
|
resetState: () => this.#resetState(),
|
|
16312
16639
|
setRunning: (running) => this.#setRunning(running)
|
|
@@ -16388,11 +16715,32 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16388
16715
|
* from {@link registerPageState}, which exposes host state as ordinary tools.
|
|
16389
16716
|
*/
|
|
16390
16717
|
get sharedState() {
|
|
16391
|
-
return this.#
|
|
16718
|
+
return this.#liveClient()?.state ?? this.#sharedState;
|
|
16392
16719
|
}
|
|
16393
16720
|
set sharedState(state) {
|
|
16394
16721
|
this.#sharedState = { ...state };
|
|
16395
|
-
this.#
|
|
16722
|
+
this.#liveClient()?.setState(this.#sharedState);
|
|
16723
|
+
}
|
|
16724
|
+
/**
|
|
16725
|
+
* The client holding the conversation's live shared state: a checkpoint
|
|
16726
|
+
* continuation while one runs, otherwise the conversation's own client, and
|
|
16727
|
+
* `null` before either exists.
|
|
16728
|
+
*
|
|
16729
|
+
* The continuation first, because the state it streams is applied to its own
|
|
16730
|
+
* agent. Reading the conversation's client alone returned what the state was
|
|
16731
|
+
* before the continuation began, for as long as that client lived.
|
|
16732
|
+
*
|
|
16733
|
+
* It now lives no longer than the continuation's first save, which hands the
|
|
16734
|
+
* conversation to the next client built, seeded from the mirror every client
|
|
16735
|
+
* writes -- so the next run sends what the continuation left. That release
|
|
16736
|
+
* alone makes the getter's fallback give the same answer, and no test can
|
|
16737
|
+
* tell the two apart; reading the continuation keeps the getter right
|
|
16738
|
+
* without depending on when the other client is let go. The setter has no
|
|
16739
|
+
* such fallback, and is held by "reads the shared state it changed while it
|
|
16740
|
+
* runs, not the conversation's" in `ag_ui_chat_checkpoints.test.ts`.
|
|
16741
|
+
*/
|
|
16742
|
+
#liveClient() {
|
|
16743
|
+
return this.#history.continuation ?? this.#client;
|
|
16396
16744
|
}
|
|
16397
16745
|
/** Bind a piece of host page state to `read_<name>` / `set_<name>` tools. */
|
|
16398
16746
|
registerPageState(binding) {
|
|
@@ -16569,6 +16917,11 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16569
16917
|
this.setAttribute("data-tool-display", value);
|
|
16570
16918
|
}
|
|
16571
16919
|
connectedCallback() {
|
|
16920
|
+
this.#connection = new AbortController();
|
|
16921
|
+
if (this.#connectedBefore) {
|
|
16922
|
+
this.#resetConversation();
|
|
16923
|
+
}
|
|
16924
|
+
this.#connectedBefore = true;
|
|
16572
16925
|
this.#storage.claim();
|
|
16573
16926
|
this.#placement.restoreSize();
|
|
16574
16927
|
requestAnimationFrame(() => {
|
|
@@ -16590,13 +16943,13 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16590
16943
|
}
|
|
16591
16944
|
this.#syncLauncher();
|
|
16592
16945
|
this.#skills.init();
|
|
16593
|
-
this.conversationStore = this.#storage.scopeStore(this
|
|
16946
|
+
this.conversationStore = this.#storage.scopeStore(this.#unwrappedStore(), this.userKey);
|
|
16594
16947
|
window.addEventListener("resize", this.#onViewportResize);
|
|
16595
16948
|
window.visualViewport?.addEventListener("resize", this.#onViewportResize);
|
|
16596
16949
|
window.visualViewport?.addEventListener("scroll", this.#onViewportResize);
|
|
16597
16950
|
this.#placement.publishVisualViewport();
|
|
16598
16951
|
this.#wireThreadStore();
|
|
16599
|
-
this.#attachments.wire();
|
|
16952
|
+
this.#attachments.wire(this.#connection.signal);
|
|
16600
16953
|
this.#voice.wire();
|
|
16601
16954
|
this.#history.adoptActiveThread();
|
|
16602
16955
|
queueMicrotask(() => this.#startup());
|
|
@@ -16661,6 +17014,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16661
17014
|
*/
|
|
16662
17015
|
disconnectedCallback() {
|
|
16663
17016
|
this.#connected = false;
|
|
17017
|
+
this.#connection.abort();
|
|
16664
17018
|
window.removeEventListener("resize", this.#onViewportResize);
|
|
16665
17019
|
window.visualViewport?.removeEventListener("resize", this.#onViewportResize);
|
|
16666
17020
|
window.visualViewport?.removeEventListener("scroll", this.#onViewportResize);
|
|
@@ -16768,17 +17122,34 @@ var AgUiChat = class extends HTMLElement {
|
|
|
16768
17122
|
* thread id, the navigation checkpoint) keep their local store either way.
|
|
16769
17123
|
*/
|
|
16770
17124
|
#wireThreadStore() {
|
|
17125
|
+
this.#threadStore = null;
|
|
16771
17126
|
const url = this.getAttribute("data-threads-url");
|
|
16772
17127
|
if (url !== null) {
|
|
16773
|
-
this.conversationStore
|
|
17128
|
+
const inner = this.conversationStore;
|
|
17129
|
+
const remote = new RemoteConversationStore(
|
|
16774
17130
|
url,
|
|
16775
17131
|
() => this.#headersFor(url),
|
|
16776
|
-
|
|
17132
|
+
inner,
|
|
16777
17133
|
() => this.#requestCredentials(),
|
|
16778
17134
|
this.getAttribute("data-threads-cache") !== "false"
|
|
16779
17135
|
);
|
|
17136
|
+
this.#threadStore = { remote, inner };
|
|
17137
|
+
this.conversationStore = remote;
|
|
16780
17138
|
}
|
|
16781
17139
|
}
|
|
17140
|
+
/**
|
|
17141
|
+
* The conversation store without the remote this element wrapped it in.
|
|
17142
|
+
*
|
|
17143
|
+
* An element removed and inserted again connects again, and wrapping the
|
|
17144
|
+
* wrapper stacked a second remote on the first, so every rename and delete
|
|
17145
|
+
* reached the server twice. Unwrapping first also lets a `data-threads-url`
|
|
17146
|
+
* removed while detached take the remote away. A store the host assigned
|
|
17147
|
+
* since is theirs, and comes back as it is.
|
|
17148
|
+
*/
|
|
17149
|
+
#unwrappedStore() {
|
|
17150
|
+
const wrapped = this.#threadStore;
|
|
17151
|
+
return wrapped !== null && this.conversationStore === wrapped.remote ? wrapped.inner : this.conversationStore;
|
|
17152
|
+
}
|
|
16782
17153
|
/**
|
|
16783
17154
|
* Replace the host-supplied (client) skill catalog. Merged after the embedded
|
|
16784
17155
|
* and fetched skills (so a client skill overrides a same-named server one).
|
|
@@ -17020,12 +17391,22 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17020
17391
|
}
|
|
17021
17392
|
/** Drop the in-memory run + transcript, leaving the thread id untouched. */
|
|
17022
17393
|
#resetState() {
|
|
17394
|
+
this.#resetConversation();
|
|
17395
|
+
this.#sentDrafts.length = 0;
|
|
17396
|
+
this.#recallIndex = null;
|
|
17397
|
+
}
|
|
17398
|
+
/**
|
|
17399
|
+
* Drop the in-memory run and transcript, and nothing the user typed.
|
|
17400
|
+
*
|
|
17401
|
+
* Split from {@link #resetState} for re-insertion, which rebuilds the
|
|
17402
|
+
* conversation from history but is not a new one, so the composer's recall
|
|
17403
|
+
* history stays.
|
|
17404
|
+
*/
|
|
17405
|
+
#resetConversation() {
|
|
17023
17406
|
this.#client = null;
|
|
17024
17407
|
this.#runHandlers.detach();
|
|
17025
17408
|
this.#clearTranscript();
|
|
17026
17409
|
this.#history.forgetRestored();
|
|
17027
|
-
this.#sentDrafts.length = 0;
|
|
17028
|
-
this.#recallIndex = null;
|
|
17029
17410
|
}
|
|
17030
17411
|
/**
|
|
17031
17412
|
* Wipe the rendered transcript and everything that indexes into it.
|
|
@@ -17091,7 +17472,19 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17091
17472
|
appendMessage(role, content) {
|
|
17092
17473
|
return this.#transcript.append(role, content);
|
|
17093
17474
|
}
|
|
17475
|
+
/**
|
|
17476
|
+
* Build the chrome, from the attributes as they stand.
|
|
17477
|
+
*
|
|
17478
|
+
* Runs on every connect, not once, because removing and re-inserting the
|
|
17479
|
+
* element is the documented way to apply a connect-time attribute written
|
|
17480
|
+
* late. So it has to build the same element the second time as the first:
|
|
17481
|
+
* the elements made here are new each time, the long-lived ones it fills
|
|
17482
|
+
* are filled with `replaceChildren` rather than appended to, and every
|
|
17483
|
+
* listener on a long-lived one goes under the connection's signal. Appending
|
|
17484
|
+
* gave a re-inserted element two headers and two composers.
|
|
17485
|
+
*/
|
|
17094
17486
|
#render() {
|
|
17487
|
+
const { signal } = this.#connection;
|
|
17095
17488
|
this.#chat.className = "chat";
|
|
17096
17489
|
this.#chat.setAttribute("part", "panel");
|
|
17097
17490
|
const header = document.createElement("div");
|
|
@@ -17128,7 +17521,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17128
17521
|
this.#themeToggle.setAttribute("part", "header-button theme-toggle");
|
|
17129
17522
|
this.#themeToggle.title = this.#strings.toggleTheme;
|
|
17130
17523
|
this.#themeToggle.setAttribute("aria-label", this.#strings.toggleTheme);
|
|
17131
|
-
this.#themeToggle.addEventListener("click", () => this.toggleTheme());
|
|
17524
|
+
this.#themeToggle.addEventListener("click", () => this.toggleTheme(), { signal });
|
|
17132
17525
|
this.#syncThemeGlyph();
|
|
17133
17526
|
controls.append(this.#themeToggle);
|
|
17134
17527
|
}
|
|
@@ -17144,8 +17537,8 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17144
17537
|
this.#jumpButton.type = "button";
|
|
17145
17538
|
this.#jumpButton.setAttribute("part", "jump-latest");
|
|
17146
17539
|
this.#jumpButton.textContent = this.#strings.jumpToLatest;
|
|
17147
|
-
this.#excerpts.mount();
|
|
17148
|
-
this.#transcript.mountScroller(this.#jumpButton);
|
|
17540
|
+
this.#excerpts.mount(signal);
|
|
17541
|
+
this.#transcript.mountScroller(this.#jumpButton, signal);
|
|
17149
17542
|
this.#announcer.mount();
|
|
17150
17543
|
this.#emptyWrap.className = "empty";
|
|
17151
17544
|
this.#emptyWrap.setAttribute("part", "empty");
|
|
@@ -17157,7 +17550,6 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17157
17550
|
greetingSlot.append(this.#greetingText);
|
|
17158
17551
|
greeting.append(greetingSlot);
|
|
17159
17552
|
this.#syncGreeting();
|
|
17160
|
-
this.#emptyWrap.append(greeting);
|
|
17161
17553
|
const emptySlot = document.createElement("slot");
|
|
17162
17554
|
emptySlot.name = "empty";
|
|
17163
17555
|
const starters = renderStarterChips(this, this.#strings, (prompt) => {
|
|
@@ -17166,7 +17558,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17166
17558
|
if (starters !== null) {
|
|
17167
17559
|
emptySlot.append(starters);
|
|
17168
17560
|
}
|
|
17169
|
-
this.#emptyWrap.
|
|
17561
|
+
this.#emptyWrap.replaceChildren(greeting, emptySlot);
|
|
17170
17562
|
this.#queuedRow.className = "queued";
|
|
17171
17563
|
this.#queuedRow.setAttribute("part", "queued");
|
|
17172
17564
|
this.#queuedRow.setAttribute("role", "group");
|
|
@@ -17188,41 +17580,47 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17188
17580
|
this.#input.setAttribute("aria-label", this.#strings.message);
|
|
17189
17581
|
this.#input.rows = 1;
|
|
17190
17582
|
this.#input.placeholder = this.#strings.inputPlaceholder;
|
|
17191
|
-
this.#input.addEventListener("keydown", (event) => this.#onKeydown(event));
|
|
17192
|
-
this.#input.addEventListener("input", () => this.#onInput());
|
|
17583
|
+
this.#input.addEventListener("keydown", (event) => this.#onKeydown(event), { signal });
|
|
17584
|
+
this.#input.addEventListener("input", () => this.#onInput(), { signal });
|
|
17193
17585
|
this.#send.className = "send";
|
|
17194
17586
|
this.#send.type = "button";
|
|
17195
17587
|
this.#send.setAttribute("part", "send");
|
|
17196
|
-
this.#send.
|
|
17588
|
+
this.#send.replaceChildren(
|
|
17197
17589
|
glyphSlot("icon-send", "send-send", ICON_SEND),
|
|
17198
17590
|
glyphSlot("icon-stop", "send-stop", ICON_STOP)
|
|
17199
17591
|
);
|
|
17200
17592
|
this.#send.title = this.#strings.send;
|
|
17201
17593
|
this.#send.setAttribute("aria-label", this.#strings.send);
|
|
17202
17594
|
this.#send.dataset["state"] = "idle";
|
|
17203
|
-
this.#send.addEventListener(
|
|
17204
|
-
|
|
17205
|
-
|
|
17206
|
-
|
|
17207
|
-
|
|
17208
|
-
|
|
17209
|
-
|
|
17595
|
+
this.#send.addEventListener(
|
|
17596
|
+
"click",
|
|
17597
|
+
() => {
|
|
17598
|
+
if (this.#running) {
|
|
17599
|
+
this.#cancelRun();
|
|
17600
|
+
return;
|
|
17601
|
+
}
|
|
17602
|
+
void this.#submit();
|
|
17603
|
+
},
|
|
17604
|
+
{ signal }
|
|
17605
|
+
);
|
|
17210
17606
|
this.#composerHint.className = "skill-hint";
|
|
17211
17607
|
this.#composerHint.setAttribute("part", "skill-hint");
|
|
17212
17608
|
this.#composerHint.hidden = true;
|
|
17213
17609
|
this.#attachButton.className = "attach-btn";
|
|
17214
17610
|
this.#attachButton.type = "button";
|
|
17215
17611
|
this.#attachButton.setAttribute("part", "attach-button");
|
|
17216
|
-
this.#attachButton.
|
|
17612
|
+
this.#attachButton.replaceChildren(glyphSlot("icon-attach", "attach-glyph", ICON_ATTACH));
|
|
17217
17613
|
this.#attachButton.title = this.#strings.attachFiles;
|
|
17218
17614
|
this.#attachButton.setAttribute("aria-label", this.#strings.attachFiles);
|
|
17219
17615
|
this.#attachButton.hidden = true;
|
|
17220
|
-
this.#attachButton.addEventListener("click", () => this.#fileInput.click());
|
|
17616
|
+
this.#attachButton.addEventListener("click", () => this.#fileInput.click(), { signal });
|
|
17221
17617
|
this.#fileInput.className = "attach-input";
|
|
17222
17618
|
this.#fileInput.type = "file";
|
|
17223
17619
|
this.#fileInput.multiple = true;
|
|
17224
17620
|
this.#fileInput.hidden = true;
|
|
17225
|
-
this.#fileInput.addEventListener("change", () => this.#attachments.onFilesPicked()
|
|
17621
|
+
this.#fileInput.addEventListener("change", () => this.#attachments.onFilesPicked(), {
|
|
17622
|
+
signal
|
|
17623
|
+
});
|
|
17226
17624
|
this.#attachSlot.className = "attachment-slot";
|
|
17227
17625
|
this.#voiceSlot.className = "voice-slot";
|
|
17228
17626
|
const footer = document.createElement("slot");
|
|
@@ -17231,8 +17629,8 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17231
17629
|
composer.append(this.#input, tools);
|
|
17232
17630
|
inputRow.append(composer, this.#fileInput);
|
|
17233
17631
|
this.#messagesWrap.className = "messages-wrap";
|
|
17234
|
-
this.#messagesWrap.
|
|
17235
|
-
this.#chat.
|
|
17632
|
+
this.#messagesWrap.replaceChildren(this.#messages, this.#jumpButton, this.#excerpts.button);
|
|
17633
|
+
this.#chat.replaceChildren(
|
|
17236
17634
|
header,
|
|
17237
17635
|
this.#messagesWrap,
|
|
17238
17636
|
this.#skillsMenu.palette,
|
|
@@ -17245,16 +17643,20 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17245
17643
|
this.#drawer.element,
|
|
17246
17644
|
this.#checkpoints.element
|
|
17247
17645
|
);
|
|
17248
|
-
this.#chat.addEventListener(
|
|
17249
|
-
|
|
17250
|
-
|
|
17251
|
-
|
|
17252
|
-
|
|
17253
|
-
|
|
17254
|
-
|
|
17255
|
-
|
|
17256
|
-
|
|
17257
|
-
|
|
17646
|
+
this.#chat.addEventListener(
|
|
17647
|
+
"pointerdown",
|
|
17648
|
+
(event) => {
|
|
17649
|
+
if (!this.#checkpoints.open_) {
|
|
17650
|
+
return;
|
|
17651
|
+
}
|
|
17652
|
+
const path = event.composedPath();
|
|
17653
|
+
if (path.includes(this.#checkpoints.element) || path.includes(checkpoints)) {
|
|
17654
|
+
return;
|
|
17655
|
+
}
|
|
17656
|
+
this.#checkpoints.close();
|
|
17657
|
+
},
|
|
17658
|
+
{ signal }
|
|
17659
|
+
);
|
|
17258
17660
|
this.#launcher.className = "launcher";
|
|
17259
17661
|
this.#launcher.type = "button";
|
|
17260
17662
|
this.#launcher.setAttribute("part", "launcher");
|
|
@@ -17267,19 +17669,19 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17267
17669
|
this.#railLabel.setAttribute("part", "rail-label");
|
|
17268
17670
|
this.#railLabel.setAttribute("aria-hidden", "true");
|
|
17269
17671
|
this.#railLabel.textContent = this.getAttribute("title-text") ?? this.#strings.title;
|
|
17270
|
-
this.#launcher.
|
|
17672
|
+
this.#launcher.replaceChildren(
|
|
17271
17673
|
iconElement("launcher", "launcher-icon", ICON_LAUNCHER, readLauncherIconUrl(this)),
|
|
17272
17674
|
this.#railLabel,
|
|
17273
17675
|
this.#badge
|
|
17274
17676
|
);
|
|
17275
|
-
this.#launcher.addEventListener("click", () => this.setCollapsed(false));
|
|
17276
|
-
this.#placement.enableLauncherDrag();
|
|
17677
|
+
this.#launcher.addEventListener("click", () => this.setCollapsed(false), { signal });
|
|
17678
|
+
this.#placement.enableLauncherDrag(signal);
|
|
17277
17679
|
this.#placement.mountResizeGrips(this.#chat);
|
|
17278
17680
|
adoptStyles(this.#root);
|
|
17279
17681
|
const probe = this.#placement.probe;
|
|
17280
17682
|
probe.className = "viewport-probe";
|
|
17281
17683
|
probe.setAttribute("aria-hidden", "true");
|
|
17282
|
-
this.#root.
|
|
17684
|
+
this.#root.replaceChildren(probe, this.#announcer.region, this.#chat, this.#launcher);
|
|
17283
17685
|
}
|
|
17284
17686
|
/**
|
|
17285
17687
|
* Reflect the collapsed state and the unread count on the launcher.
|
|
@@ -17434,6 +17836,9 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17434
17836
|
* other shape would be a second sender racing the guard above.
|
|
17435
17837
|
*/
|
|
17436
17838
|
#flushQueued() {
|
|
17839
|
+
if (this.#running || this.#history.continuation !== null) {
|
|
17840
|
+
return;
|
|
17841
|
+
}
|
|
17437
17842
|
const next = this.#queued.shift();
|
|
17438
17843
|
this.#renderQueued();
|
|
17439
17844
|
if (next !== void 0) {
|
|
@@ -17471,7 +17876,7 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17471
17876
|
if (content === "" && attachments.length === 0) {
|
|
17472
17877
|
return;
|
|
17473
17878
|
}
|
|
17474
|
-
if (this.#running) {
|
|
17879
|
+
if (this.#running || this.#history.continuation !== null) {
|
|
17475
17880
|
if (content !== "") {
|
|
17476
17881
|
this.#queued.push(content);
|
|
17477
17882
|
this.#renderQueued();
|
|
@@ -17509,12 +17914,14 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17509
17914
|
* `attachments` are durable {@link AttachmentRef}s — what {@link attachFile}
|
|
17510
17915
|
* resolves to and what {@link ATTACHMENT_EVENT} reports.
|
|
17511
17916
|
*
|
|
17512
|
-
* No-ops on an empty message, and while a run
|
|
17513
|
-
*
|
|
17514
|
-
*
|
|
17917
|
+
* No-ops on an empty message, and while a run or a picked checkpoint's
|
|
17918
|
+
* continuation is in flight, since a second concurrent run would orphan the
|
|
17919
|
+
* first. Unlike the built-in Send it does not queue: it returns, and the
|
|
17920
|
+
* caller keeps what it tried to send. Nor does it consult the tray -- what
|
|
17921
|
+
* you pass is what is sent.
|
|
17515
17922
|
*/
|
|
17516
17923
|
async sendMessage(content, attachments = []) {
|
|
17517
|
-
if (this.#running || content === "" && attachments.length === 0) {
|
|
17924
|
+
if (this.#running || this.#history.continuation !== null || content === "" && attachments.length === 0) {
|
|
17518
17925
|
return;
|
|
17519
17926
|
}
|
|
17520
17927
|
if (this.#transcript.isEmpty()) {
|
|
@@ -17587,7 +17994,8 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17587
17994
|
this.#client = this.#buildClient({
|
|
17588
17995
|
endpoint: this.endpoint,
|
|
17589
17996
|
initialMessages: this.#history.restored,
|
|
17590
|
-
|
|
17997
|
+
// Its history is the whole conversation, so nothing goes ahead of it.
|
|
17998
|
+
follows: []
|
|
17591
17999
|
});
|
|
17592
18000
|
}
|
|
17593
18001
|
return this.#client;
|
|
@@ -17624,9 +18032,15 @@ var AgUiChat = class extends HTMLElement {
|
|
|
17624
18032
|
getContext: () => this.#dispatch.buildContext(),
|
|
17625
18033
|
executeTool: (call) => this.#dispatch.execute(call),
|
|
17626
18034
|
resolveInterrupts: (interrupts) => this.#dispatch.resolveInterrupts(interrupts),
|
|
17627
|
-
|
|
17628
|
-
|
|
17629
|
-
|
|
18035
|
+
// Every client saves the whole conversation, because a store keeps one
|
|
18036
|
+
// list per thread. For the conversation's own client that is its
|
|
18037
|
+
// history; a continuation holds only what it adds, and writes the
|
|
18038
|
+
// conversation it continues ahead of that.
|
|
18039
|
+
onPersist: (messages) => {
|
|
18040
|
+
const conversation = [...seed.follows, ...messages];
|
|
18041
|
+
this.conversationStore.saveMessages(threadId, conversation);
|
|
18042
|
+
seed.onSaved?.(conversation);
|
|
18043
|
+
},
|
|
17630
18044
|
onStateChanged: (state) => this.#onSharedStateChanged(state),
|
|
17631
18045
|
connectionLostMessage: this.#strings.connectionLost,
|
|
17632
18046
|
unfinishedMessage: this.#strings.callNotFinished,
|
|
@@ -17789,7 +18203,7 @@ function setControlValue(el2, value) {
|
|
|
17789
18203
|
}
|
|
17790
18204
|
|
|
17791
18205
|
// src/version.ts
|
|
17792
|
-
var VERSION = "0.
|
|
18206
|
+
var VERSION = "0.41.0";
|
|
17793
18207
|
export {
|
|
17794
18208
|
ATTACHMENT_EVENT,
|
|
17795
18209
|
AgUiChat,
|
|
@@ -17887,6 +18301,6 @@ export {
|
|
|
17887
18301
|
/*! Bundled license information:
|
|
17888
18302
|
|
|
17889
18303
|
dompurify/dist/purify.es.mjs:
|
|
17890
|
-
(*! @license DOMPurify 3.4.
|
|
18304
|
+
(*! @license DOMPurify 3.4.15 | (c) Cure53 and other contributors | Released under the Apache license 2.0 and Mozilla Public License 2.0 | github.com/cure53/DOMPurify/blob/3.4.15/LICENSE *)
|
|
17891
18305
|
*/
|
|
17892
18306
|
//# sourceMappingURL=index.js.map
|