@prettier-ai/dsh-client-ui-chat 0.1.2-rc.1 → 0.1.3-alpha.1
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/lib/client.js +670 -161
- package/lib/types/client/chat/ChatNodeSeat.d.ts +1 -1
- package/lib/types/client/contract/assistant-content.d.ts +1 -1
- package/lib/types/client/contract/slots.d.ts +9 -2
- package/lib/types/client/contract/turn-metrics.d.ts +1 -1
- package/lib/types/client/conversation-nodes/assistant.d.ts +1 -2
- package/lib/types/client/conversation-nodes/chat-snapshot-builder.d.ts +55 -1
- package/lib/types/client/conversation-nodes/command.d.ts +1 -2
- package/lib/types/client/conversation-nodes/compaction.d.ts +1 -2
- package/lib/types/client/conversation-nodes/event-projection.d.ts +6 -0
- package/lib/types/client/conversation-nodes/fallback.d.ts +1 -2
- package/lib/types/client/conversation-nodes/message.d.ts +5 -2
- package/lib/types/client/conversation-nodes/partial.d.ts +2 -2
- package/lib/types/client/conversation-nodes/retry.d.ts +1 -2
- package/lib/types/client/conversation-nodes/tool.d.ts +1 -2
- package/lib/types/client/conversation-nodes/turn-error.d.ts +1 -2
- package/lib/types/client/conversation-nodes/turn-max-tokens.d.ts +1 -2
- package/lib/types/client/model/conversation-context.d.ts +1 -2
- package/lib/types/client/model/tool-call-tree.d.ts +1 -1
- package/package.json +28 -28
package/lib/client.js
CHANGED
|
@@ -27,7 +27,8 @@ window.__ModuleLoader__.load({
|
|
|
27
27
|
function resolveWorkspacePath(cwd, path) {
|
|
28
28
|
if (path.startsWith("/") || isWindowsStylePath(path)) return path;
|
|
29
29
|
if (cwd === void 0 || cwd === "") return path;
|
|
30
|
-
|
|
30
|
+
const separator = isWindowsStylePath(cwd) && cwd.includes("\\") ? "\\" : "/";
|
|
31
|
+
return `${cwd.replace(/[/\\]+$/, "")}${separator}${path.replace(/^[/\\]+/, "")}`;
|
|
31
32
|
}
|
|
32
33
|
//#endregion
|
|
33
34
|
//#region lib/types/client/contract/snapshot.js
|
|
@@ -115,7 +116,7 @@ window.__ModuleLoader__.load({
|
|
|
115
116
|
}
|
|
116
117
|
//#endregion
|
|
117
118
|
//#region \0dsh-css:/home/runner/work/dsh-publisher/dsh-publisher/upstream/packages/client/ui-chat/src/client/chat/MessageItem.module.css.mjs
|
|
118
|
-
const css$15 = ".-EE-uG_userRow{flex-direction:column;align-items:flex-end;gap:6px;display:flex}.-EE-uG_userStack{min-width:0;max-width:min(calc(var(--dsh-chat-content-width,748px) * .702), 82%);flex-direction:column;align-items:flex-end;gap:8px;display:flex}.-EE-uG_bubble{background:var(--dsw-specific-bubble);max-width:100%;font-size:var(--dsh-content-font-size,14px);line-height:calc(22px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;border-radius:22px;padding:10px 16px}.-EE-uG_referenceSummary{color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(18px + var(--dsh-content-font-delta-secondary,0px))}.-EE-uG_contextRow,.-EE-uG_compactionRow{padding:2px 0}.-EE-uG_compactionButton{width:100%;height:calc(24px + var(--dsh-content-font-delta,0px));min-width:0;color:inherit;font:inherit;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;padding:0;display:flex}.-EE-uG_compactionButton:not(:disabled){cursor:pointer}.-EE-uG_compactionButton:not(:disabled):hover{background:var(--dsw-alias-interactive-bg-hover)}.-EE-uG_compactionLeading{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-secondary);flex:none;place-items:center;margin-right:6px;display:inline-grid}.-EE-uG_compactionLeading svg{width:calc(14px + var(--dsh-content-font-delta,0px));height:calc(14px + var(--dsh-content-font-delta,0px))}.-EE-uG_compactionContextIcon,.-EE-uG_compactionDisclosureIcon{grid-area:1/1;justify-content:center;align-items:center;display:inline-flex}.-EE-uG_compactionDisclosureIcon,.-EE-uG_compactionButton:not(:disabled):hover .-EE-uG_compactionContextIcon,.-EE-uG_compactionButton:not(:disabled):focus-visible .-EE-uG_compactionContextIcon{opacity:0}.-EE-uG_compactionButton:not(:disabled):hover .-EE-uG_compactionDisclosureIcon,.-EE-uG_compactionButton:not(:disabled):focus-visible .-EE-uG_compactionDisclosureIcon{opacity:1}.-EE-uG_compactionTitle{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-primary-dimmed);flex:none}.-EE-uG_compactionSep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.-EE-uG_compactionSummary{min-width:0;color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));text-overflow:ellipsis;white-space:nowrap;flex:auto;overflow:hidden}.-EE-uG_compactionBody{padding:4px 0 4px calc(22px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px))}.-EE-uG_retryRow{color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px))}.-EE-uG_retrySummary{width:fit-content;color:inherit;cursor:pointer;user-select:none;border-radius:3px;align-items:center;gap:7px;padding:2px 0;list-style:none;display:inline-flex}.-EE-uG_retrySummary::-webkit-details-marker{display:none}.-EE-uG_retrySummary:after{content:\"\";opacity:.8;border-bottom:1.5px solid;border-right:1.5px solid;width:6px;height:6px;transition:transform .12s;transform:rotate(-45deg)}.-EE-uG_retrySummary:hover{color:var(--dsw-alias-label-secondary)}.-EE-uG_retrySummary:focus-visible{outline:1.5px solid var(--dsw-alias-button-info-fill);outline-offset:2px}.-EE-uG_retryText{color:inherit}.-EE-uG_retryRow[data-active] .-EE-uG_retryText{background:linear-gradient(90deg, var(--dsw-alias-label-tertiary) 0%, var(--dsw-alias-label-tertiary) 40%, var(--dsw-alias-label-secondary) 50%, var(--dsw-alias-label-tertiary) 60%, var(--dsw-alias-label-tertiary) 100%);color:#0000;background-position:100%;background-size:200% 100%;background-clip:text;animation:1.6s ease-in-out infinite -EE-uG_retry-shimmer}.-EE-uG_retryRow[open] .-EE-uG_retrySummary:after{transform:rotate(45deg)}.-EE-uG_retryDetails{overflow-wrap:anywhere;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(18px + var(--dsh-content-font-delta-secondary,0px));gap:2px;margin-top:3px;padding-left:14px;display:grid}.-EE-uG_retryDetailLabel{color:var(--dsw-alias-label-secondary)}.-EE-uG_turnErrorRow{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px));grid-template-columns:10px minmax(0,1fr) auto;align-items:start;gap:8px;padding:2px 0;display:grid}.-EE-uG_turnErrorDot{margin-top:5px}.-EE-uG_turnErrorCopy{overflow-wrap:anywhere;min-width:0}.-EE-uG_turnErrorTitle{color:var(--dsw-alias-state-error-primary);margin-right:6px;font-weight:600}.-EE-uG_turnErrorMessage{color:var(--dsw-alias-label-secondary)}.-EE-uG_turnErrorCode{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-markdown-code-block-small)}.-EE-uG_maxTokensTitle{color:var(--dsw-alias-state-warn-primary);margin-right:6px;font-weight:600}@keyframes -EE-uG_retry-shimmer{0%{background-position:100%}to{background-position:0}}@media (prefers-reduced-motion:reduce){.-EE-uG_retryRow[data-active] .-EE-uG_retryText{color:inherit;background:0 0;animation:none}}";
|
|
119
|
+
const css$15 = ".-EE-uG_userRow{flex-direction:column;align-items:flex-end;gap:6px;display:flex}.-EE-uG_userStack{min-width:0;max-width:min(calc(var(--dsh-chat-content-width,748px) * .702), 82%);flex-direction:column;align-items:flex-end;gap:8px;display:flex}.-EE-uG_bubble{background:var(--dsw-specific-bubble);max-width:100%;font-size:var(--dsh-content-font-size,14px);line-height:calc(22px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-primary);white-space:pre-wrap;word-break:break-word;border-radius:22px;padding:10px 16px}.-EE-uG_referenceSummary{color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(18px + var(--dsh-content-font-delta-secondary,0px))}.-EE-uG_contextRow,.-EE-uG_compactionRow{padding:2px 0}.-EE-uG_compactionButton{width:100%;height:calc(24px + var(--dsh-content-font-delta,0px));min-width:0;color:inherit;font:inherit;text-align:left;background:0 0;border:none;border-radius:6px;align-items:center;padding:0;display:flex}.-EE-uG_compactionButton:not(:disabled){cursor:pointer}.-EE-uG_compactionButton:not(:disabled):hover{background:var(--dsw-alias-interactive-bg-hover)}.-EE-uG_compactionLeading{width:calc(16px + var(--dsh-content-font-delta,0px));height:calc(16px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-secondary);flex:none;place-items:center;margin-right:6px;display:inline-grid}.-EE-uG_compactionLeading svg{width:calc(14px + var(--dsh-content-font-delta,0px));height:calc(14px + var(--dsh-content-font-delta,0px))}.-EE-uG_compactionContextIcon,.-EE-uG_compactionDisclosureIcon{grid-area:1/1;justify-content:center;align-items:center;display:inline-flex}.-EE-uG_compactionDisclosureIcon,.-EE-uG_compactionButton:not(:disabled):hover .-EE-uG_compactionContextIcon,.-EE-uG_compactionButton:not(:disabled):focus-visible .-EE-uG_compactionContextIcon{opacity:0}.-EE-uG_compactionButton:not(:disabled):hover .-EE-uG_compactionDisclosureIcon,.-EE-uG_compactionButton:not(:disabled):focus-visible .-EE-uG_compactionDisclosureIcon{opacity:1}.-EE-uG_compactionTitle{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-primary-dimmed);flex:none}.-EE-uG_compactionSep{background:var(--dsw-alias-label-caption);border-radius:1px;flex:none;width:2px;height:2px;margin:0 8px}.-EE-uG_compactionSummary{min-width:0;color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px));text-overflow:ellipsis;white-space:nowrap;flex:auto;overflow:hidden}.-EE-uG_compactionBody{padding:4px 0 4px calc(22px + var(--dsh-content-font-delta,0px));color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(24px + var(--dsh-content-font-delta,0px))}.-EE-uG_retryRow{color:var(--dsw-alias-label-tertiary);font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px))}.-EE-uG_retrySummary{width:fit-content;color:inherit;cursor:pointer;user-select:none;border-radius:3px;align-items:center;gap:7px;padding:2px 0;list-style:none;display:inline-flex}.-EE-uG_retrySummary::-webkit-details-marker{display:none}.-EE-uG_retrySummary:after{content:\"\";opacity:.8;border-bottom:1.5px solid;border-right:1.5px solid;width:6px;height:6px;transition:transform .12s;transform:rotate(-45deg)}.-EE-uG_retrySummary:hover{color:var(--dsw-alias-label-secondary)}.-EE-uG_retrySummary:focus-visible{outline:1.5px solid var(--dsw-alias-button-info-fill);outline-offset:2px}.-EE-uG_retryText{color:inherit}.-EE-uG_retryRow[data-active] .-EE-uG_retryText{background:linear-gradient(90deg, var(--dsw-alias-label-tertiary) 0%, var(--dsw-alias-label-tertiary) 40%, var(--dsw-alias-label-secondary) 50%, var(--dsw-alias-label-tertiary) 60%, var(--dsw-alias-label-tertiary) 100%);color:#0000;background-position:100%;background-size:200% 100%;background-clip:text;animation:1.6s ease-in-out infinite -EE-uG_retry-shimmer}.-EE-uG_retryRow[open] .-EE-uG_retrySummary:after{transform:rotate(45deg)}.-EE-uG_retryDetails{overflow-wrap:anywhere;font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(18px + var(--dsh-content-font-delta-secondary,0px));gap:2px;margin-top:3px;padding-left:14px;display:grid}.-EE-uG_retryDetailLabel{color:var(--dsw-alias-label-secondary)}.-EE-uG_turnErrorRow{font-size:var(--dsh-content-font-size-secondary,13px);line-height:calc(20px + var(--dsh-content-font-delta-secondary,0px));grid-template-columns:10px minmax(0,1fr) auto;align-items:start;gap:8px;padding:2px 0;display:grid}.-EE-uG_turnErrorDot{margin-top:5px}.-EE-uG_turnErrorCopy{overflow-wrap:anywhere;min-width:0}.-EE-uG_turnErrorTitle{color:var(--dsw-alias-state-error-primary);margin-right:6px;font-weight:600}.-EE-uG_turnErrorMessage{color:var(--dsw-alias-label-secondary)}.-EE-uG_turnErrorCode{color:var(--dsw-alias-label-tertiary);font:var(--dsw-font-markdown-code-block-small)}.-EE-uG_maxTokensTitle{color:var(--dsw-alias-state-warn-primary);margin-right:6px;font-weight:600}@keyframes -EE-uG_retry-shimmer{0%{background-position:100%}to{background-position:0}}@media (prefers-reduced-motion:reduce){.-EE-uG_retryRow[data-active] .-EE-uG_retryText{color:inherit;background:0 0;animation:none}}.-EE-uG_attachmentRow{flex-wrap:wrap;justify-content:flex-end;gap:8px;max-width:100%;display:flex}.-EE-uG_fileCard{border:.5px solid var(--dsw-alias-border-l2,#0000001f);background:var(--dsw-specific-input-major,transparent);box-sizing:border-box;border-radius:16px;flex:0 0 240px;align-items:center;gap:10px;width:240px;min-height:64px;padding:8px 12px;display:inline-flex}.-EE-uG_fileIcon{flex:none;width:24px;height:28px}.-EE-uG_fileContent{flex-direction:column;flex:1;min-width:0;display:flex}.-EE-uG_fileName{white-space:nowrap;text-overflow:ellipsis;color:var(--dsw-alias-label-primary);font-size:14px;font-weight:500;line-height:22px;overflow:hidden}.-EE-uG_fileMeta{white-space:nowrap;text-overflow:ellipsis;color:var(--dsw-alias-label-tertiary,#00000073);font-size:12px;line-height:15px;overflow:hidden}";
|
|
119
120
|
const tagId$15 = "@prettier-ai/dsh-client-ui-chat/MessageItem.module.css";
|
|
120
121
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$15) + "]") === null) {
|
|
121
122
|
const tag = document.createElement("style");
|
|
@@ -125,6 +126,7 @@ window.__ModuleLoader__.load({
|
|
|
125
126
|
document.head.appendChild(tag);
|
|
126
127
|
}
|
|
127
128
|
var MessageItem_module_css_default = {
|
|
129
|
+
"attachmentRow": "-EE-uG_attachmentRow",
|
|
128
130
|
"bubble": "-EE-uG_bubble",
|
|
129
131
|
"compactionBody": "-EE-uG_compactionBody",
|
|
130
132
|
"compactionButton": "-EE-uG_compactionButton",
|
|
@@ -136,6 +138,11 @@ window.__ModuleLoader__.load({
|
|
|
136
138
|
"compactionSummary": "-EE-uG_compactionSummary",
|
|
137
139
|
"compactionTitle": "-EE-uG_compactionTitle",
|
|
138
140
|
"contextRow": "-EE-uG_contextRow",
|
|
141
|
+
"fileCard": "-EE-uG_fileCard",
|
|
142
|
+
"fileContent": "-EE-uG_fileContent",
|
|
143
|
+
"fileIcon": "-EE-uG_fileIcon",
|
|
144
|
+
"fileMeta": "-EE-uG_fileMeta",
|
|
145
|
+
"fileName": "-EE-uG_fileName",
|
|
139
146
|
"maxTokensTitle": "-EE-uG_maxTokensTitle",
|
|
140
147
|
"referenceSummary": "-EE-uG_referenceSummary",
|
|
141
148
|
"retry-shimmer": "-EE-uG_retry-shimmer",
|
|
@@ -1054,19 +1061,31 @@ window.__ModuleLoader__.load({
|
|
|
1054
1061
|
}
|
|
1055
1062
|
//#endregion
|
|
1056
1063
|
//#region lib/types/client/chat/MessageItem.js
|
|
1064
|
+
function extensionOf(name) {
|
|
1065
|
+
const dot = name.lastIndexOf(".");
|
|
1066
|
+
if (dot <= 0 || dot === name.length - 1) return "";
|
|
1067
|
+
return name.slice(dot + 1).toUpperCase().slice(0, 8);
|
|
1068
|
+
}
|
|
1057
1069
|
function contentParts(content) {
|
|
1058
1070
|
const texts = [];
|
|
1059
|
-
const
|
|
1071
|
+
const attachments = [];
|
|
1060
1072
|
const rest = [];
|
|
1061
1073
|
for (const block of content) {
|
|
1062
1074
|
const b = block;
|
|
1063
1075
|
if (b.type === "text" && typeof b.text === "string") texts.push(b.text);
|
|
1064
|
-
else if (b.type === "image" && b.attachment !== void 0)
|
|
1076
|
+
else if (b.type === "image" && b.attachment !== void 0) attachments.push({
|
|
1077
|
+
type: "image",
|
|
1078
|
+
image: { attachment: b.attachment }
|
|
1079
|
+
});
|
|
1080
|
+
else if (b.type === "file" && b.attachment !== void 0) attachments.push({
|
|
1081
|
+
type: "file",
|
|
1082
|
+
file: b.attachment
|
|
1083
|
+
});
|
|
1065
1084
|
else rest.push(block);
|
|
1066
1085
|
}
|
|
1067
1086
|
return {
|
|
1068
1087
|
text: texts.join(""),
|
|
1069
|
-
|
|
1088
|
+
attachments,
|
|
1070
1089
|
rest
|
|
1071
1090
|
};
|
|
1072
1091
|
}
|
|
@@ -1180,9 +1199,10 @@ window.__ModuleLoader__.load({
|
|
|
1180
1199
|
});
|
|
1181
1200
|
}
|
|
1182
1201
|
/** Right-aligned bubble shared by user and steering rows. */
|
|
1183
|
-
function UserStyleBubble({ content, renderMessageImages, actions, pending = false, echo = false, referenceLabels = [],
|
|
1184
|
-
const { text,
|
|
1185
|
-
const
|
|
1202
|
+
function UserStyleBubble({ content, renderMessageImages, actions, pending = false, echo = false, referenceLabels = [], skillNames = [], previewAttachments, t }) {
|
|
1203
|
+
const { text, attachments: contentAttachments, rest } = contentParts(content);
|
|
1204
|
+
const attachments = previewAttachments ?? contentAttachments;
|
|
1205
|
+
const compactImages = attachments.length > 1;
|
|
1186
1206
|
const truncated = (total) => t("json.truncated", { total });
|
|
1187
1207
|
const showBubble = text !== "" || rest.length > 0;
|
|
1188
1208
|
return (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -1192,13 +1212,31 @@ window.__ModuleLoader__.load({
|
|
|
1192
1212
|
children: [(0, react_jsx_runtime.jsxs)("div", {
|
|
1193
1213
|
className: MessageItem_module_css_default.userStack,
|
|
1194
1214
|
children: [
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1215
|
+
attachments.length > 0 && (0, react_jsx_runtime.jsx)("div", {
|
|
1216
|
+
className: MessageItem_module_css_default.attachmentRow,
|
|
1217
|
+
"data-message-attachments": true,
|
|
1218
|
+
children: attachments.map((attachment, index) => attachment.type === "image" ? (0, react_jsx_runtime.jsx)(react.Fragment, { children: renderMessageImages({
|
|
1219
|
+
images: [attachment.image],
|
|
1220
|
+
align: "end",
|
|
1221
|
+
compact: compactImages
|
|
1222
|
+
}) }, `image:${index}`) : (0, react_jsx_runtime.jsxs)("span", {
|
|
1223
|
+
className: MessageItem_module_css_default.fileCard,
|
|
1224
|
+
title: attachment.file.name,
|
|
1225
|
+
children: [(0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.DocumentFileIcon, { className: MessageItem_module_css_default.fileIcon }), (0, react_jsx_runtime.jsxs)("span", {
|
|
1226
|
+
className: MessageItem_module_css_default.fileContent,
|
|
1227
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
1228
|
+
className: MessageItem_module_css_default.fileName,
|
|
1229
|
+
children: attachment.file.name
|
|
1230
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
1231
|
+
className: MessageItem_module_css_default.fileMeta,
|
|
1232
|
+
children: [extensionOf(attachment.file.name), (0, _prettier_ai_dsh_client_ui_primitives.fileSizeText)(attachment.file.bytes)].filter(Boolean).join(" ")
|
|
1233
|
+
})]
|
|
1234
|
+
})]
|
|
1235
|
+
}, `file:${index}`))
|
|
1198
1236
|
}),
|
|
1199
1237
|
showBubble && (0, react_jsx_runtime.jsxs)("div", {
|
|
1200
1238
|
className: MessageItem_module_css_default.bubble,
|
|
1201
|
-
children: [(0, _prettier_ai_dsh_client_ui_primitives.projectUserText)(text, referenceLabels), rest.map((block, i) => (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
1239
|
+
children: [(0, _prettier_ai_dsh_client_ui_primitives.projectUserText)(text, referenceLabels, skillNames), rest.map((block, i) => (0, react_jsx_runtime.jsx)(_prettier_ai_dsh_client_ui_primitives.JsonBlock, {
|
|
1202
1240
|
label: t("message.extraBlock"),
|
|
1203
1241
|
payload: block,
|
|
1204
1242
|
truncatedLabel: truncated
|
|
@@ -1246,12 +1284,18 @@ window.__ModuleLoader__.load({
|
|
|
1246
1284
|
type: "text",
|
|
1247
1285
|
text: submission.text
|
|
1248
1286
|
}], [submission.text]),
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1287
|
+
previewAttachments: (0, react.useMemo)(() => submission.attachments.map((attachment) => attachment.type === "image" ? {
|
|
1288
|
+
type: "image",
|
|
1289
|
+
image: { preview: {
|
|
1290
|
+
url: attachment.value.previewUrl,
|
|
1291
|
+
...attachment.value.name === void 0 ? {} : { name: attachment.value.name },
|
|
1292
|
+
...attachment.value.width === void 0 ? {} : { width: attachment.value.width },
|
|
1293
|
+
...attachment.value.height === void 0 ? {} : { height: attachment.value.height }
|
|
1294
|
+
} }
|
|
1295
|
+
} : {
|
|
1296
|
+
type: "file",
|
|
1297
|
+
file: attachment.value
|
|
1298
|
+
}), [submission.attachments]),
|
|
1255
1299
|
renderMessageImages,
|
|
1256
1300
|
pending: submission.placement === "steering",
|
|
1257
1301
|
echo: true,
|
|
@@ -1272,6 +1316,7 @@ window.__ModuleLoader__.load({
|
|
|
1272
1316
|
content: data.content,
|
|
1273
1317
|
renderMessageImages,
|
|
1274
1318
|
...data.referenceLabels === void 0 ? {} : { referenceLabels: data.referenceLabels },
|
|
1319
|
+
...data.skillNames === void 0 ? {} : { skillNames: data.skillNames },
|
|
1275
1320
|
t,
|
|
1276
1321
|
actions: (text) => (0, react_jsx_runtime.jsx)(MessageIconActions, {
|
|
1277
1322
|
text,
|
|
@@ -1470,7 +1515,7 @@ window.__ModuleLoader__.load({
|
|
|
1470
1515
|
return location?.kind === "turn" || location?.kind === "step" ? location.turn.turn : void 0;
|
|
1471
1516
|
}
|
|
1472
1517
|
/** Subscribe, apply Turn-process visibility, and dispatch one stable Context key. */
|
|
1473
|
-
const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, useChatNode, useChatNodeProcess, historyIncomplete, compactTranscript, selectedCallId, cwd, openFile, inspectCall, forkAt, renderMessageImages, fileMentions, useStore, actions, renderSlot, t }) {
|
|
1518
|
+
const ChatNodeSeat = (0, react.memo)(function ChatNodeSeat({ nodeKey, useChatNode, useChatNodeProcess, historyIncomplete, compactTranscript, selectedCallId, cwd, openFile, inspectCall, forkAt, loadImage, renderMessageImages, fileMentions, useStore, actions, renderSlot, t }) {
|
|
1474
1519
|
const node = useChatNode(nodeKey);
|
|
1475
1520
|
const routedNode = node;
|
|
1476
1521
|
const turn = turnOf(routedNode);
|
|
@@ -1509,6 +1554,7 @@ window.__ModuleLoader__.load({
|
|
|
1509
1554
|
openFile,
|
|
1510
1555
|
inspectCall,
|
|
1511
1556
|
forkAt,
|
|
1557
|
+
loadImage,
|
|
1512
1558
|
renderMessageImages,
|
|
1513
1559
|
fileMentions,
|
|
1514
1560
|
turnProcess
|
|
@@ -1519,6 +1565,7 @@ window.__ModuleLoader__.load({
|
|
|
1519
1565
|
openFile,
|
|
1520
1566
|
inspectCall,
|
|
1521
1567
|
forkAt,
|
|
1568
|
+
loadImage,
|
|
1522
1569
|
renderMessageImages,
|
|
1523
1570
|
fileMentions,
|
|
1524
1571
|
turnProcess
|
|
@@ -2468,6 +2515,7 @@ window.__ModuleLoader__.load({
|
|
|
2468
2515
|
openFile: requestOpenFile,
|
|
2469
2516
|
inspectCall,
|
|
2470
2517
|
forkAt,
|
|
2518
|
+
loadImage,
|
|
2471
2519
|
renderMessageImages,
|
|
2472
2520
|
fileMentions,
|
|
2473
2521
|
renderSlot,
|
|
@@ -3902,6 +3950,345 @@ window.__ModuleLoader__.load({
|
|
|
3902
3950
|
});
|
|
3903
3951
|
});
|
|
3904
3952
|
//#endregion
|
|
3953
|
+
//#region ../../util/values/src/index.ts
|
|
3954
|
+
/** Whether a realm-owned intrinsic prototype is backed by its native constructor. */
|
|
3955
|
+
function hasIntrinsicConstructor(prototype, name) {
|
|
3956
|
+
const constructor = Object.getOwnPropertyDescriptor(prototype, "constructor")?.value;
|
|
3957
|
+
if (typeof constructor !== "function") return false;
|
|
3958
|
+
try {
|
|
3959
|
+
return constructor.name === name && constructor.prototype === prototype && Function.prototype.toString.call(constructor) === `function ${name}() { [native code] }`;
|
|
3960
|
+
} catch {
|
|
3961
|
+
return false;
|
|
3962
|
+
}
|
|
3963
|
+
}
|
|
3964
|
+
/** Whether a candidate is one realm's intrinsic `Object.prototype`. */
|
|
3965
|
+
function isIntrinsicObjectPrototype(value) {
|
|
3966
|
+
return Object.getPrototypeOf(value) === null && hasIntrinsicConstructor(value, "Object");
|
|
3967
|
+
}
|
|
3968
|
+
/** Whether an array uses one realm's intrinsic `Array.prototype`, not a subclass or forged prototype. */
|
|
3969
|
+
function hasPlainArrayPrototype(value) {
|
|
3970
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3971
|
+
if (!Array.isArray(prototype) || !hasIntrinsicConstructor(prototype, "Array")) return false;
|
|
3972
|
+
const objectPrototype = Object.getPrototypeOf(prototype);
|
|
3973
|
+
return typeof objectPrototype === "object" && objectPrototype !== null && isIntrinsicObjectPrototype(objectPrototype);
|
|
3974
|
+
}
|
|
3975
|
+
/** Whether an object is a plain or null-prototype record from any JavaScript realm. */
|
|
3976
|
+
function hasPlainObjectPrototype(value) {
|
|
3977
|
+
const prototype = Object.getPrototypeOf(value);
|
|
3978
|
+
return prototype === null || typeof prototype === "object" && isIntrinsicObjectPrototype(prototype);
|
|
3979
|
+
}
|
|
3980
|
+
/** Return every JSON-visible object key, or reject own data JSON would discard. */
|
|
3981
|
+
function enumerableStringKeys(value) {
|
|
3982
|
+
const keys = Reflect.ownKeys(value);
|
|
3983
|
+
if (keys.some((key) => typeof key !== "string" || !Object.prototype.propertyIsEnumerable.call(value, key))) return void 0;
|
|
3984
|
+
return keys;
|
|
3985
|
+
}
|
|
3986
|
+
/** Validate lossless JSON iteratively, optionally materializing a detached snapshot. */
|
|
3987
|
+
function walkJsonValue(value, detach) {
|
|
3988
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
3989
|
+
let root;
|
|
3990
|
+
const assign = (destination, item) => {
|
|
3991
|
+
if (destination === void 0) return;
|
|
3992
|
+
if (destination.kind === "root") root = item;
|
|
3993
|
+
else if (destination.kind === "array") destination.target[destination.index] = item;
|
|
3994
|
+
else Object.defineProperty(destination.target, destination.key, {
|
|
3995
|
+
value: item,
|
|
3996
|
+
enumerable: true,
|
|
3997
|
+
configurable: true,
|
|
3998
|
+
writable: true
|
|
3999
|
+
});
|
|
4000
|
+
};
|
|
4001
|
+
const tasks = [{
|
|
4002
|
+
kind: "visit",
|
|
4003
|
+
value,
|
|
4004
|
+
...detach ? { destination: { kind: "root" } } : {}
|
|
4005
|
+
}];
|
|
4006
|
+
for (let task = tasks.pop(); task !== void 0; task = tasks.pop()) {
|
|
4007
|
+
if (task.kind === "leave") {
|
|
4008
|
+
ancestors.delete(task.source);
|
|
4009
|
+
continue;
|
|
4010
|
+
}
|
|
4011
|
+
if (task.kind === "array-item") {
|
|
4012
|
+
if (!Object.prototype.hasOwnProperty.call(task.source, task.index)) return void 0;
|
|
4013
|
+
tasks.push({
|
|
4014
|
+
kind: "visit",
|
|
4015
|
+
value: task.source[task.index],
|
|
4016
|
+
...task.target === void 0 ? {} : { destination: {
|
|
4017
|
+
kind: "array",
|
|
4018
|
+
target: task.target,
|
|
4019
|
+
index: task.index
|
|
4020
|
+
} }
|
|
4021
|
+
});
|
|
4022
|
+
continue;
|
|
4023
|
+
}
|
|
4024
|
+
if (task.kind === "object-property") {
|
|
4025
|
+
tasks.push({
|
|
4026
|
+
kind: "visit",
|
|
4027
|
+
value: task.source[task.key],
|
|
4028
|
+
...task.target === void 0 ? {} : { destination: {
|
|
4029
|
+
kind: "object",
|
|
4030
|
+
target: task.target,
|
|
4031
|
+
key: task.key
|
|
4032
|
+
} }
|
|
4033
|
+
});
|
|
4034
|
+
continue;
|
|
4035
|
+
}
|
|
4036
|
+
const current = task.value;
|
|
4037
|
+
if (current === null) {
|
|
4038
|
+
assign(task.destination, null);
|
|
4039
|
+
continue;
|
|
4040
|
+
}
|
|
4041
|
+
if (typeof current === "boolean" || typeof current === "string") {
|
|
4042
|
+
assign(task.destination, current);
|
|
4043
|
+
continue;
|
|
4044
|
+
}
|
|
4045
|
+
if (typeof current === "number") {
|
|
4046
|
+
if (!Number.isFinite(current) || Object.is(current, -0)) return void 0;
|
|
4047
|
+
assign(task.destination, current);
|
|
4048
|
+
continue;
|
|
4049
|
+
}
|
|
4050
|
+
if (typeof current !== "object") return void 0;
|
|
4051
|
+
if (ancestors.has(current)) return void 0;
|
|
4052
|
+
if (Array.isArray(current)) {
|
|
4053
|
+
if (!hasPlainArrayPrototype(current)) return void 0;
|
|
4054
|
+
const length = current.length;
|
|
4055
|
+
if (Reflect.ownKeys(current).length !== length + 1) return void 0;
|
|
4056
|
+
const target = detach ? [] : void 0;
|
|
4057
|
+
if (target !== void 0) assign(task.destination, target);
|
|
4058
|
+
ancestors.add(current);
|
|
4059
|
+
tasks.push({
|
|
4060
|
+
kind: "leave",
|
|
4061
|
+
source: current
|
|
4062
|
+
});
|
|
4063
|
+
for (let index = length - 1; index >= 0; index--) tasks.push({
|
|
4064
|
+
kind: "array-item",
|
|
4065
|
+
source: current,
|
|
4066
|
+
index,
|
|
4067
|
+
...target === void 0 ? {} : { target }
|
|
4068
|
+
});
|
|
4069
|
+
continue;
|
|
4070
|
+
}
|
|
4071
|
+
if (!hasPlainObjectPrototype(current)) return void 0;
|
|
4072
|
+
const keys = enumerableStringKeys(current);
|
|
4073
|
+
if (keys === void 0) return void 0;
|
|
4074
|
+
const target = detach ? {} : void 0;
|
|
4075
|
+
if (target !== void 0) assign(task.destination, target);
|
|
4076
|
+
ancestors.add(current);
|
|
4077
|
+
tasks.push({
|
|
4078
|
+
kind: "leave",
|
|
4079
|
+
source: current
|
|
4080
|
+
});
|
|
4081
|
+
for (let index = keys.length - 1; index >= 0; index--) {
|
|
4082
|
+
const key = keys[index];
|
|
4083
|
+
/* v8 ignore next -- the loop is bounded by the captured key count. */
|
|
4084
|
+
if (key === void 0) return void 0;
|
|
4085
|
+
tasks.push({
|
|
4086
|
+
kind: "object-property",
|
|
4087
|
+
source: current,
|
|
4088
|
+
key,
|
|
4089
|
+
...target === void 0 ? {} : { target }
|
|
4090
|
+
});
|
|
4091
|
+
}
|
|
4092
|
+
}
|
|
4093
|
+
return detach ? root : true;
|
|
4094
|
+
}
|
|
4095
|
+
/**
|
|
4096
|
+
* Validate and detach lossless JSON in one read per property.
|
|
4097
|
+
* @param value - candidate value to validate and detach.
|
|
4098
|
+
* @returns the detached snapshot, or `undefined` when the value is not losslessly JSON-serializable.
|
|
4099
|
+
*/
|
|
4100
|
+
function snapshotJsonValue(value) {
|
|
4101
|
+
return walkJsonValue(value, true);
|
|
4102
|
+
}
|
|
4103
|
+
/**
|
|
4104
|
+
* Deep-freeze an object graph in place while leaving live AbortSignal objects mutable.
|
|
4105
|
+
* @param value - value to freeze.
|
|
4106
|
+
* @returns the same value after every reachable enumerable child is frozen.
|
|
4107
|
+
*/
|
|
4108
|
+
function deepFreeze(value) {
|
|
4109
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
4110
|
+
const pending = [{
|
|
4111
|
+
kind: "visit",
|
|
4112
|
+
node: value
|
|
4113
|
+
}];
|
|
4114
|
+
while (pending.length > 0) {
|
|
4115
|
+
const task = pending.pop();
|
|
4116
|
+
/* v8 ignore next -- the loop condition guarantees one pending task. */
|
|
4117
|
+
if (task === void 0) continue;
|
|
4118
|
+
if (task.kind === "property") {
|
|
4119
|
+
pending.push({
|
|
4120
|
+
kind: "visit",
|
|
4121
|
+
node: task.source[task.key]
|
|
4122
|
+
});
|
|
4123
|
+
continue;
|
|
4124
|
+
}
|
|
4125
|
+
const node = task.node;
|
|
4126
|
+
if (node === null || typeof node !== "object") continue;
|
|
4127
|
+
if (node instanceof AbortSignal) continue;
|
|
4128
|
+
if (seen.has(node)) continue;
|
|
4129
|
+
seen.add(node);
|
|
4130
|
+
Object.freeze(node);
|
|
4131
|
+
const keys = Object.keys(node);
|
|
4132
|
+
for (let index = keys.length - 1; index >= 0; index--) {
|
|
4133
|
+
const key = keys[index];
|
|
4134
|
+
/* v8 ignore next -- the loop is bounded by the captured key count. */
|
|
4135
|
+
if (key === void 0) continue;
|
|
4136
|
+
pending.push({
|
|
4137
|
+
kind: "property",
|
|
4138
|
+
source: node,
|
|
4139
|
+
key
|
|
4140
|
+
});
|
|
4141
|
+
}
|
|
4142
|
+
}
|
|
4143
|
+
return value;
|
|
4144
|
+
}
|
|
4145
|
+
//#endregion
|
|
4146
|
+
//#region ../../llm/llm/src/assistant-stream.ts
|
|
4147
|
+
/** Lossless compact representation of one model-stream attempt. */
|
|
4148
|
+
function safeTime(value) {
|
|
4149
|
+
if (!Number.isSafeInteger(value)) throw new TypeError(`Assistant stream time must be a safe integer, got ${String(value)}`);
|
|
4150
|
+
return value;
|
|
4151
|
+
}
|
|
4152
|
+
function safeIndex(value, label) {
|
|
4153
|
+
if (!Number.isSafeInteger(value) || value < 0 || Object.is(value, -0)) throw new TypeError(`${label} index must be a non-negative safe integer`);
|
|
4154
|
+
return value;
|
|
4155
|
+
}
|
|
4156
|
+
function snapshotChunk(chunk) {
|
|
4157
|
+
const snapshot = snapshotJsonValue(chunk);
|
|
4158
|
+
if (snapshot === void 0) throw new TypeError("Assistant stream chunk must be losslessly JSON-serializable");
|
|
4159
|
+
return snapshot;
|
|
4160
|
+
}
|
|
4161
|
+
/**
|
|
4162
|
+
* Expand compact records into the exact timed chunk sequence.
|
|
4163
|
+
* @param stream - compact records from one durable Assistant settlement.
|
|
4164
|
+
* @returns detached timed chunks with every original delta boundary preserved.
|
|
4165
|
+
* @throws {TypeError} when a record or reconstructed timestamp is invalid.
|
|
4166
|
+
*/
|
|
4167
|
+
function expandAssistantStream(stream) {
|
|
4168
|
+
const chunks = [];
|
|
4169
|
+
for (const candidate of stream) {
|
|
4170
|
+
const record = validateRecord(candidate);
|
|
4171
|
+
if (record.type === "chunk") {
|
|
4172
|
+
chunks.push({
|
|
4173
|
+
time: record.time,
|
|
4174
|
+
chunk: record.chunk
|
|
4175
|
+
});
|
|
4176
|
+
continue;
|
|
4177
|
+
}
|
|
4178
|
+
const members = record.type === "tool-call-chunks" ? record.args : record.texts;
|
|
4179
|
+
let time = record.time0;
|
|
4180
|
+
for (let index = 0; index < members.length; index += 1) {
|
|
4181
|
+
if (index > 0) time += record.dt[index - 1];
|
|
4182
|
+
let chunk;
|
|
4183
|
+
if (record.type === "text-chunks") chunk = {
|
|
4184
|
+
type: "text-delta",
|
|
4185
|
+
index: record.index,
|
|
4186
|
+
text: members[index]
|
|
4187
|
+
};
|
|
4188
|
+
else if (record.type === "reasoning-chunks") chunk = {
|
|
4189
|
+
type: "reasoning-delta",
|
|
4190
|
+
index: record.index,
|
|
4191
|
+
text: members[index]
|
|
4192
|
+
};
|
|
4193
|
+
else chunk = {
|
|
4194
|
+
type: "tool-call-delta",
|
|
4195
|
+
index: record.index,
|
|
4196
|
+
id: record.id,
|
|
4197
|
+
...Object.hasOwn(record, "name") ? { name: record.name } : {},
|
|
4198
|
+
argumentsDelta: members[index]
|
|
4199
|
+
};
|
|
4200
|
+
chunks.push({
|
|
4201
|
+
time,
|
|
4202
|
+
chunk
|
|
4203
|
+
});
|
|
4204
|
+
}
|
|
4205
|
+
}
|
|
4206
|
+
return chunks;
|
|
4207
|
+
}
|
|
4208
|
+
function validateRecord(value) {
|
|
4209
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) throw new TypeError("Assistant stream record must be an object");
|
|
4210
|
+
const record = value;
|
|
4211
|
+
switch (record.type) {
|
|
4212
|
+
case "text-chunks":
|
|
4213
|
+
case "reasoning-chunks": {
|
|
4214
|
+
exactKeys(record, [
|
|
4215
|
+
"type",
|
|
4216
|
+
"time0",
|
|
4217
|
+
"index",
|
|
4218
|
+
"dt",
|
|
4219
|
+
"texts"
|
|
4220
|
+
], record.type);
|
|
4221
|
+
const texts = stringArray(record.texts, `${record.type} texts`);
|
|
4222
|
+
if (texts.length === 0) throw new TypeError(`${record.type} texts must be non-empty`);
|
|
4223
|
+
validateRun(record, texts.length, record.type);
|
|
4224
|
+
return record;
|
|
4225
|
+
}
|
|
4226
|
+
case "tool-call-chunks": {
|
|
4227
|
+
exactKeys(record, Object.hasOwn(record, "name") ? [
|
|
4228
|
+
"type",
|
|
4229
|
+
"time0",
|
|
4230
|
+
"index",
|
|
4231
|
+
"dt",
|
|
4232
|
+
"id",
|
|
4233
|
+
"name",
|
|
4234
|
+
"args"
|
|
4235
|
+
] : [
|
|
4236
|
+
"type",
|
|
4237
|
+
"time0",
|
|
4238
|
+
"index",
|
|
4239
|
+
"dt",
|
|
4240
|
+
"id",
|
|
4241
|
+
"args"
|
|
4242
|
+
], record.type);
|
|
4243
|
+
const args = stringArray(record.args, "tool-call-chunks args");
|
|
4244
|
+
if (args.length === 0) throw new TypeError("tool-call-chunks args must be non-empty");
|
|
4245
|
+
if (typeof record.id !== "string" || record.id.length === 0) throw new TypeError("tool-call-chunks id must be a non-empty string");
|
|
4246
|
+
if (record.name !== void 0 && (typeof record.name !== "string" || record.name.length === 0)) throw new TypeError("tool-call-chunks name must be a non-empty string");
|
|
4247
|
+
validateRun(record, args.length, record.type);
|
|
4248
|
+
return record;
|
|
4249
|
+
}
|
|
4250
|
+
case "chunk": {
|
|
4251
|
+
exactKeys(record, [
|
|
4252
|
+
"type",
|
|
4253
|
+
"time",
|
|
4254
|
+
"chunk"
|
|
4255
|
+
], "chunk");
|
|
4256
|
+
const time = safeTime(record.time);
|
|
4257
|
+
if (typeof record.chunk !== "object" || record.chunk === null || Array.isArray(record.chunk)) throw new TypeError("Assistant stream raw chunk must be a lossless JSON object");
|
|
4258
|
+
let chunk;
|
|
4259
|
+
try {
|
|
4260
|
+
chunk = snapshotChunk(record.chunk);
|
|
4261
|
+
} catch (error) {
|
|
4262
|
+
throw new TypeError("Assistant stream raw chunk must be a lossless JSON object", { cause: error });
|
|
4263
|
+
}
|
|
4264
|
+
return deepFreeze({
|
|
4265
|
+
type: "chunk",
|
|
4266
|
+
time,
|
|
4267
|
+
chunk
|
|
4268
|
+
});
|
|
4269
|
+
}
|
|
4270
|
+
default: throw new TypeError(`Unsupported Assistant stream record ${JSON.stringify(record.type)}`);
|
|
4271
|
+
}
|
|
4272
|
+
}
|
|
4273
|
+
function validateRun(record, members, label) {
|
|
4274
|
+
safeTime(record.time0);
|
|
4275
|
+
safeIndex(record.index, label);
|
|
4276
|
+
if (!Array.isArray(record.dt) || record.dt.some((value) => !Number.isSafeInteger(value))) throw new TypeError(`${label} dt must contain safe integers`);
|
|
4277
|
+
if (record.dt.length !== members - 1) throw new TypeError(`${label} dt length must be one less than its members`);
|
|
4278
|
+
let time = record.time0;
|
|
4279
|
+
for (const gap of record.dt) {
|
|
4280
|
+
time += gap;
|
|
4281
|
+
if (!Number.isSafeInteger(time)) throw new TypeError(`${label} member times must stay safe integers`);
|
|
4282
|
+
}
|
|
4283
|
+
}
|
|
4284
|
+
function stringArray(value, label) {
|
|
4285
|
+
if (!Array.isArray(value) || value.some((member) => typeof member !== "string")) throw new TypeError(`${label} must be a string array`);
|
|
4286
|
+
return value;
|
|
4287
|
+
}
|
|
4288
|
+
function exactKeys(record, keys, label) {
|
|
4289
|
+
if (Object.keys(record).length !== keys.length || !keys.every((key) => Object.hasOwn(record, key))) throw new TypeError(`${label} Assistant stream record must contain exactly ${keys.join(", ")}`);
|
|
4290
|
+
}
|
|
4291
|
+
//#endregion
|
|
3905
4292
|
//#region ../../core/session/src/surface.ts
|
|
3906
4293
|
/** Runtime counterpart of the message-producing event union. */
|
|
3907
4294
|
const SURFACE_EVENT_TYPES = new Set([
|
|
@@ -4075,6 +4462,16 @@ window.__ModuleLoader__.load({
|
|
|
4075
4462
|
return collect(record, "references", "label");
|
|
4076
4463
|
}
|
|
4077
4464
|
/**
|
|
4465
|
+
* Read the skill name a durable skill-invocation injection loaded.
|
|
4466
|
+
* @param source - Logged `user/message` source.
|
|
4467
|
+
* @returns The skill name, or null for every other source.
|
|
4468
|
+
*/
|
|
4469
|
+
function skillInvocationName(source) {
|
|
4470
|
+
const record = asRecord(source);
|
|
4471
|
+
if (record === null || readString(record, "kind") !== "skill-invocation") return null;
|
|
4472
|
+
return readString(record, "name");
|
|
4473
|
+
}
|
|
4474
|
+
/**
|
|
4078
4475
|
* Classify finalized Assistant content for Chat rendering.
|
|
4079
4476
|
* @param content - Core content blocks.
|
|
4080
4477
|
* @returns Chat blocks in source order.
|
|
@@ -4173,9 +4570,6 @@ window.__ModuleLoader__.load({
|
|
|
4173
4570
|
}
|
|
4174
4571
|
//#endregion
|
|
4175
4572
|
//#region lib/types/client/conversation-nodes/assistant.js
|
|
4176
|
-
function isChunkRunEvent$1(event) {
|
|
4177
|
-
return event.type === "chunkrow/text-chunks" || event.type === "chunkrow/reasoning-chunks" || event.type === "chunkrow/tool-call-chunks";
|
|
4178
|
-
}
|
|
4179
4573
|
function initialState(turn, step) {
|
|
4180
4574
|
return {
|
|
4181
4575
|
turn,
|
|
@@ -4219,9 +4613,7 @@ window.__ModuleLoader__.load({
|
|
|
4219
4613
|
hidden: true
|
|
4220
4614
|
};
|
|
4221
4615
|
}
|
|
4222
|
-
function updateChunk(state,
|
|
4223
|
-
if (match.event.type !== "assistant/chunk") return state;
|
|
4224
|
-
const chunk = match.event.data.chunk;
|
|
4616
|
+
function updateChunk(state, chunk, seq, time) {
|
|
4225
4617
|
const blocks = [...state.blocks];
|
|
4226
4618
|
let changedIndex = -1;
|
|
4227
4619
|
let previousVisible = false;
|
|
@@ -4288,79 +4680,16 @@ window.__ModuleLoader__.load({
|
|
|
4288
4680
|
visibleBlocks,
|
|
4289
4681
|
hidden: visibleBlocks > 0 ? false : state.hidden,
|
|
4290
4682
|
...visibleBlocks > 0 && state.firstVisibleSeq === void 0 ? {
|
|
4291
|
-
firstVisibleSeq:
|
|
4292
|
-
firstVisibleTime:
|
|
4683
|
+
firstVisibleSeq: seq,
|
|
4684
|
+
firstVisibleTime: time
|
|
4293
4685
|
} : {},
|
|
4294
|
-
...firstToken && state.firstTokenTime === void 0 ? { firstTokenTime:
|
|
4295
|
-
};
|
|
4296
|
-
}
|
|
4297
|
-
function chunkRunBoundaries(event, needsToken, needsVisible, visibleFromStart) {
|
|
4298
|
-
const fragments = event.type === "chunkrow/tool-call-chunks" ? event.data.args : event.data.texts;
|
|
4299
|
-
const nameStartsToken = event.type === "chunkrow/tool-call-chunks" && Object.hasOwn(event.data, "name");
|
|
4300
|
-
let firstTokenTime;
|
|
4301
|
-
let firstVisible;
|
|
4302
|
-
let time = event.time;
|
|
4303
|
-
for (let index = 0; index < fragments.length; index++) {
|
|
4304
|
-
const fragment = fragments[index];
|
|
4305
|
-
if (needsToken && firstTokenTime === void 0 && (nameStartsToken || fragment !== "")) firstTokenTime = time;
|
|
4306
|
-
if (needsVisible && firstVisible === void 0 && (visibleFromStart || event.type !== "chunkrow/tool-call-chunks" && fragment.trim() !== "")) firstVisible = {
|
|
4307
|
-
seq: event.seq + index,
|
|
4308
|
-
time
|
|
4309
|
-
};
|
|
4310
|
-
if ((!needsToken || firstTokenTime !== void 0) && (!needsVisible || firstVisible !== void 0)) break;
|
|
4311
|
-
time += event.data.dt[index] ?? 0;
|
|
4312
|
-
}
|
|
4313
|
-
return {
|
|
4314
|
-
firstTokenTime,
|
|
4315
|
-
firstVisible
|
|
4686
|
+
...firstToken && state.firstTokenTime === void 0 ? { firstTokenTime: time } : {}
|
|
4316
4687
|
};
|
|
4317
4688
|
}
|
|
4318
|
-
function
|
|
4319
|
-
|
|
4320
|
-
const
|
|
4321
|
-
|
|
4322
|
-
let visibleFromStart = state.visibleBlocks - Number(previousVisible) > 0;
|
|
4323
|
-
if (event.type === "chunkrow/text-chunks") {
|
|
4324
|
-
const text = previous?.kind === "text" ? previous.text : "";
|
|
4325
|
-
visibleFromStart ||= text.trim() !== "";
|
|
4326
|
-
blocks[event.data.index] = {
|
|
4327
|
-
kind: "text",
|
|
4328
|
-
text: text + event.data.texts.join("")
|
|
4329
|
-
};
|
|
4330
|
-
} else if (event.type === "chunkrow/reasoning-chunks") {
|
|
4331
|
-
const text = previous?.kind === "reasoning" ? previous.text : "";
|
|
4332
|
-
visibleFromStart ||= text.trim() !== "";
|
|
4333
|
-
blocks[event.data.index] = {
|
|
4334
|
-
kind: "reasoning",
|
|
4335
|
-
text: text + event.data.texts.join("")
|
|
4336
|
-
};
|
|
4337
|
-
} else {
|
|
4338
|
-
const base = previous?.kind === "tool-call" ? previous : {
|
|
4339
|
-
kind: "tool-call",
|
|
4340
|
-
callId: "",
|
|
4341
|
-
name: "",
|
|
4342
|
-
argsRaw: ""
|
|
4343
|
-
};
|
|
4344
|
-
blocks[event.data.index] = {
|
|
4345
|
-
kind: "tool-call",
|
|
4346
|
-
callId: base.callId || String(event.data.id),
|
|
4347
|
-
name: Object.hasOwn(event.data, "name") ? event.data.name : base.name,
|
|
4348
|
-
argsRaw: base.argsRaw + event.data.args.join("")
|
|
4349
|
-
};
|
|
4350
|
-
}
|
|
4351
|
-
const boundaries = chunkRunBoundaries(event, state.firstTokenTime === void 0, state.firstVisibleSeq === void 0, visibleFromStart);
|
|
4352
|
-
const visibleBlocks = state.visibleBlocks - Number(previousVisible) + Number(blockIsVisible(blocks[event.data.index]));
|
|
4353
|
-
return {
|
|
4354
|
-
...state,
|
|
4355
|
-
blocks,
|
|
4356
|
-
visibleBlocks,
|
|
4357
|
-
hidden: visibleBlocks > 0 ? false : state.hidden,
|
|
4358
|
-
...boundaries.firstVisible === void 0 ? {} : {
|
|
4359
|
-
firstVisibleSeq: boundaries.firstVisible.seq,
|
|
4360
|
-
firstVisibleTime: boundaries.firstVisible.time
|
|
4361
|
-
},
|
|
4362
|
-
...boundaries.firstTokenTime === void 0 ? {} : { firstTokenTime: boundaries.firstTokenTime }
|
|
4363
|
-
};
|
|
4689
|
+
function updateEmbedded(state, event) {
|
|
4690
|
+
let next = state;
|
|
4691
|
+
for (const member of expandAssistantStream(event.data.stream)) next = updateChunk(next, member.chunk, event.seq, member.time);
|
|
4692
|
+
return next;
|
|
4364
4693
|
}
|
|
4365
4694
|
function closedBoundary(location) {
|
|
4366
4695
|
if (location.kind === "step" && location.step.status === "closed" && location.step.end !== void 0) return location.step.end;
|
|
@@ -4405,15 +4734,14 @@ window.__ModuleLoader__.load({
|
|
|
4405
4734
|
function fallbackState$5(context) {
|
|
4406
4735
|
let state;
|
|
4407
4736
|
for (const match of context.matches) {
|
|
4408
|
-
if (
|
|
4737
|
+
if (match.event.type === "assistant/live-chunk") {
|
|
4409
4738
|
state ??= initialState(match.event.data.turn, match.event.data.step);
|
|
4410
|
-
state =
|
|
4739
|
+
state = updateChunk(state, match.event.data.chunk, match.event.seq, match.event.time);
|
|
4411
4740
|
continue;
|
|
4412
4741
|
}
|
|
4413
|
-
if (match.event.type === "assistant/
|
|
4742
|
+
if (match.event.type === "assistant/message" || match.event.type === "assistant/attempt") {
|
|
4414
4743
|
state ??= initialState(match.event.data.turn, match.event.data.step);
|
|
4415
|
-
state =
|
|
4416
|
-
continue;
|
|
4744
|
+
state = updateEmbedded(state, match.event);
|
|
4417
4745
|
}
|
|
4418
4746
|
if (match.event.type === "assistant/message") {
|
|
4419
4747
|
state ??= initialState(match.event.data.turn, match.event.data.step);
|
|
@@ -4469,11 +4797,7 @@ window.__ModuleLoader__.load({
|
|
|
4469
4797
|
id: `${event.data.turn}:${event.data.step}`,
|
|
4470
4798
|
role: "start"
|
|
4471
4799
|
};
|
|
4472
|
-
if (event.type === "assistant/chunk" || event.type === "assistant/message" && isAppendSurfaceEvent(event)) return {
|
|
4473
|
-
id: `${event.data.turn}:${event.data.step}`,
|
|
4474
|
-
role: "update"
|
|
4475
|
-
};
|
|
4476
|
-
if (isChunkRunEvent$1(event)) return {
|
|
4800
|
+
if (event.type === "assistant/live-chunk" || event.type === "assistant/attempt" || event.type === "assistant/message" && isAppendSurfaceEvent(event)) return {
|
|
4477
4801
|
id: `${event.data.turn}:${event.data.step}`,
|
|
4478
4802
|
role: "update"
|
|
4479
4803
|
};
|
|
@@ -4488,12 +4812,13 @@ window.__ModuleLoader__.load({
|
|
|
4488
4812
|
return initialState(match.event.data.turn, match.event.data.step);
|
|
4489
4813
|
},
|
|
4490
4814
|
update: (context, match) => {
|
|
4491
|
-
if (
|
|
4492
|
-
if (match.event.type === "assistant/
|
|
4815
|
+
if (match.event.type === "assistant/live-chunk") return updateChunk(context.state, match.event.data.chunk, match.event.seq, match.event.time);
|
|
4816
|
+
if (match.event.type === "assistant/attempt") return updateEmbedded(context.state, match.event);
|
|
4493
4817
|
if (match.event.type === "assistant/message") {
|
|
4818
|
+
const streamed = updateEmbedded(context.state, match.event);
|
|
4494
4819
|
const blocks = toAssistantBlocks(match.event.data.message.content);
|
|
4495
4820
|
return {
|
|
4496
|
-
...
|
|
4821
|
+
...streamed,
|
|
4497
4822
|
blocks,
|
|
4498
4823
|
visibleBlocks: countVisibleBlocks(blocks),
|
|
4499
4824
|
hidden: false,
|
|
@@ -4506,8 +4831,7 @@ window.__ModuleLoader__.load({
|
|
|
4506
4831
|
},
|
|
4507
4832
|
publication: (match) => {
|
|
4508
4833
|
if (match.event.type === "step/start") return "none";
|
|
4509
|
-
if (
|
|
4510
|
-
if (match.event.type !== "assistant/chunk") return "immediate";
|
|
4834
|
+
if (match.event.type !== "assistant/live-chunk") return "immediate";
|
|
4511
4835
|
const type = match.event.data.chunk.type;
|
|
4512
4836
|
return type === "usage" || type === "finish" ? "none" : "animation-frame";
|
|
4513
4837
|
},
|
|
@@ -5107,6 +5431,194 @@ window.__ModuleLoader__.load({
|
|
|
5107
5431
|
return [...byKey.values()];
|
|
5108
5432
|
}
|
|
5109
5433
|
};
|
|
5434
|
+
function withSkillNames(node, names) {
|
|
5435
|
+
const candidate = node;
|
|
5436
|
+
if (candidate.kind !== "user" && candidate.kind !== "steering") return node;
|
|
5437
|
+
const current = candidate.data.skillNames ?? EMPTY_KEYS;
|
|
5438
|
+
const hasNames = Object.hasOwn(candidate.data, "skillNames");
|
|
5439
|
+
if (sameReferences$1(current, names) && hasNames === names.length > 0) return node;
|
|
5440
|
+
const data = { ...candidate.data };
|
|
5441
|
+
if (names.length === 0) delete data.skillNames;
|
|
5442
|
+
else data.skillNames = names;
|
|
5443
|
+
return {
|
|
5444
|
+
...candidate,
|
|
5445
|
+
data
|
|
5446
|
+
};
|
|
5447
|
+
}
|
|
5448
|
+
/**
|
|
5449
|
+
* Classify one Node for batching: a direct message, a `skill-invocation`
|
|
5450
|
+
* context, or a boundary of any other kind. A context that injects no skill
|
|
5451
|
+
* (workspace rules, the catalog, a recall) is transparent and yields null.
|
|
5452
|
+
*/
|
|
5453
|
+
function slashEntryOf(node) {
|
|
5454
|
+
const candidate = node;
|
|
5455
|
+
if (candidate.kind === "user" || candidate.kind === "steering") return {
|
|
5456
|
+
key: node.key,
|
|
5457
|
+
seq: node.anchorSeq,
|
|
5458
|
+
kind: "message",
|
|
5459
|
+
name: null
|
|
5460
|
+
};
|
|
5461
|
+
if (candidate.kind === "context") {
|
|
5462
|
+
const name = skillInvocationName(candidate.data.source);
|
|
5463
|
+
return name === null ? null : {
|
|
5464
|
+
key: node.key,
|
|
5465
|
+
seq: node.anchorSeq,
|
|
5466
|
+
kind: "skill",
|
|
5467
|
+
name
|
|
5468
|
+
};
|
|
5469
|
+
}
|
|
5470
|
+
return {
|
|
5471
|
+
key: node.key,
|
|
5472
|
+
seq: node.anchorSeq,
|
|
5473
|
+
kind: "boundary",
|
|
5474
|
+
name: null
|
|
5475
|
+
};
|
|
5476
|
+
}
|
|
5477
|
+
function sameSlashEntry(left, right) {
|
|
5478
|
+
return left.seq === right.seq && left.kind === right.kind && left.name === right.name;
|
|
5479
|
+
}
|
|
5480
|
+
/**
|
|
5481
|
+
* Attaches each direct message's step-loaded skill names to its Node.
|
|
5482
|
+
*
|
|
5483
|
+
* A step's `skill-invocation` injections follow the direct messages the host
|
|
5484
|
+
* scanned for `/name` gestures and precede the step's first Node of any other
|
|
5485
|
+
* kind, so every non-message, non-context Node closes a batch. Every ended
|
|
5486
|
+
* Turn publishes its `turn-tail` Node on `turn/end` whatever the reason, so a
|
|
5487
|
+
* batch never spans Turns, and `step/start` precedes the direct message in
|
|
5488
|
+
* the log, so no boundary separates a message from its injections. Names
|
|
5489
|
+
* attach to every direct message of the batch: the bubble decorates only the
|
|
5490
|
+
* tokens its own text carries.
|
|
5491
|
+
*
|
|
5492
|
+
* The index holds only messages, skill injections, and boundaries, ordered by
|
|
5493
|
+
* `anchorSeq`. An apply re-reads just the batches around the Nodes whose
|
|
5494
|
+
* classification changed and never scans the store, so an assistant
|
|
5495
|
+
* streaming frame costs nothing here (the append hot path never scans the
|
|
5496
|
+
* Chat Nodes).
|
|
5497
|
+
*/
|
|
5498
|
+
var SkillNameProjector = class {
|
|
5499
|
+
entries = /* @__PURE__ */ new Map();
|
|
5500
|
+
/** Every indexed entry in `anchorSeq` order. */
|
|
5501
|
+
sorted = [];
|
|
5502
|
+
/**
|
|
5503
|
+
* Rebuild the index from a whole Node set and attach names to its messages.
|
|
5504
|
+
* @param nodes - every materialized Chat Node, in any order.
|
|
5505
|
+
* @returns the same Nodes, direct messages carrying their batch's names.
|
|
5506
|
+
*/
|
|
5507
|
+
replace(nodes) {
|
|
5508
|
+
this.entries.clear();
|
|
5509
|
+
this.sorted = [];
|
|
5510
|
+
for (const node of nodes) {
|
|
5511
|
+
const entry = slashEntryOf(node);
|
|
5512
|
+
if (entry === null) continue;
|
|
5513
|
+
this.entries.set(entry.key, entry);
|
|
5514
|
+
this.sorted.push(entry);
|
|
5515
|
+
}
|
|
5516
|
+
this.sorted.sort((left, right) => left.seq - right.seq);
|
|
5517
|
+
const names = /* @__PURE__ */ new Map();
|
|
5518
|
+
for (let index = 0; index < this.sorted.length; index++) {
|
|
5519
|
+
if (this.sorted[index]?.kind === "boundary") continue;
|
|
5520
|
+
const end = this.runEnd(index);
|
|
5521
|
+
this.assignRun(index, end, names);
|
|
5522
|
+
index = end;
|
|
5523
|
+
}
|
|
5524
|
+
return nodes.map((node) => withSkillNames(node, names.get(node.key) ?? EMPTY_KEYS));
|
|
5525
|
+
}
|
|
5526
|
+
/**
|
|
5527
|
+
* Fold one incremental upsert set: re-read only the batches around the
|
|
5528
|
+
* Nodes whose classification changed.
|
|
5529
|
+
* @param upserts - the changed Nodes.
|
|
5530
|
+
* @param store - the resident Nodes, read by key for the messages of an affected batch.
|
|
5531
|
+
* @returns the upserts plus any resident message whose names changed.
|
|
5532
|
+
*/
|
|
5533
|
+
apply(upserts, store) {
|
|
5534
|
+
const dirty = [];
|
|
5535
|
+
for (const node of upserts) {
|
|
5536
|
+
const next = slashEntryOf(node);
|
|
5537
|
+
const previous = this.entries.get(node.key);
|
|
5538
|
+
if (previous !== void 0) {
|
|
5539
|
+
if (next !== null && sameSlashEntry(previous, next)) {
|
|
5540
|
+
if (next.kind === "message") dirty.push(next.seq);
|
|
5541
|
+
continue;
|
|
5542
|
+
}
|
|
5543
|
+
this.remove(previous);
|
|
5544
|
+
dirty.push(previous.seq);
|
|
5545
|
+
}
|
|
5546
|
+
if (next === null) continue;
|
|
5547
|
+
this.insert(next);
|
|
5548
|
+
dirty.push(next.seq);
|
|
5549
|
+
}
|
|
5550
|
+
if (dirty.length === 0) return upserts;
|
|
5551
|
+
const names = /* @__PURE__ */ new Map();
|
|
5552
|
+
for (const seq of dirty) this.collectAround(seq, names);
|
|
5553
|
+
const byKey = new Map(upserts.map((node) => [node.key, node]));
|
|
5554
|
+
for (const [key, list] of names) {
|
|
5555
|
+
const node = byKey.get(key) ?? store.get(key);
|
|
5556
|
+
if (node === void 0) continue;
|
|
5557
|
+
const next = withSkillNames(node, list);
|
|
5558
|
+
if (next !== node || byKey.has(key)) byKey.set(key, next);
|
|
5559
|
+
}
|
|
5560
|
+
return [...byKey.values()];
|
|
5561
|
+
}
|
|
5562
|
+
insert(entry) {
|
|
5563
|
+
this.sorted.splice(this.lowerBound(entry.seq), 0, entry);
|
|
5564
|
+
this.entries.set(entry.key, entry);
|
|
5565
|
+
}
|
|
5566
|
+
remove(entry) {
|
|
5567
|
+
this.sorted.splice(this.sorted.indexOf(entry), 1);
|
|
5568
|
+
this.entries.delete(entry.key);
|
|
5569
|
+
}
|
|
5570
|
+
/** First index whose seq is at least `seq`. */
|
|
5571
|
+
lowerBound(seq) {
|
|
5572
|
+
let low = 0;
|
|
5573
|
+
let high = this.sorted.length;
|
|
5574
|
+
while (low < high) {
|
|
5575
|
+
const middle = low + high >>> 1;
|
|
5576
|
+
if ((this.sorted[middle]?.seq ?? Number.POSITIVE_INFINITY) < seq) low = middle + 1;
|
|
5577
|
+
else high = middle;
|
|
5578
|
+
}
|
|
5579
|
+
return low;
|
|
5580
|
+
}
|
|
5581
|
+
/** Last index of the boundary-free run containing `index`. */
|
|
5582
|
+
runEnd(index) {
|
|
5583
|
+
let end = index;
|
|
5584
|
+
while (end + 1 < this.sorted.length && this.sorted[end + 1]?.kind !== "boundary") end++;
|
|
5585
|
+
return end;
|
|
5586
|
+
}
|
|
5587
|
+
/** First index of the boundary-free run containing `index`. */
|
|
5588
|
+
runStart(index) {
|
|
5589
|
+
let start = index;
|
|
5590
|
+
while (start - 1 >= 0 && this.sorted[start - 1]?.kind !== "boundary") start--;
|
|
5591
|
+
return start;
|
|
5592
|
+
}
|
|
5593
|
+
/** Record the names every message of the run `[start, end]` carries. */
|
|
5594
|
+
assignRun(start, end, names) {
|
|
5595
|
+
const list = [];
|
|
5596
|
+
for (let index = start; index <= end; index++) {
|
|
5597
|
+
const entry = this.sorted[index];
|
|
5598
|
+
if (entry?.kind === "skill" && entry.name !== null && !list.includes(entry.name)) list.push(entry.name);
|
|
5599
|
+
}
|
|
5600
|
+
for (let index = start; index <= end; index++) {
|
|
5601
|
+
const entry = this.sorted[index];
|
|
5602
|
+
if (entry?.kind === "message") names.set(entry.key, list);
|
|
5603
|
+
}
|
|
5604
|
+
}
|
|
5605
|
+
/**
|
|
5606
|
+
* Re-read the run(s) around one changed seq: the run holding a message or
|
|
5607
|
+
* skill entry, or — for a boundary, or a seq that left the index — the runs
|
|
5608
|
+
* on both sides of that position.
|
|
5609
|
+
*/
|
|
5610
|
+
collectAround(seq, names) {
|
|
5611
|
+
const at = this.lowerBound(seq);
|
|
5612
|
+
const here = this.sorted[at];
|
|
5613
|
+
if (here !== void 0 && here.seq === seq && here.kind !== "boundary") {
|
|
5614
|
+
this.assignRun(this.runStart(at), this.runEnd(at), names);
|
|
5615
|
+
return;
|
|
5616
|
+
}
|
|
5617
|
+
if (at - 1 >= 0 && this.sorted[at - 1]?.kind !== "boundary") this.assignRun(this.runStart(at - 1), at - 1, names);
|
|
5618
|
+
const right = here !== void 0 && here.seq === seq ? at + 1 : at;
|
|
5619
|
+
if (right < this.sorted.length && this.sorted[right]?.kind !== "boundary") this.assignRun(right, this.runEnd(right), names);
|
|
5620
|
+
}
|
|
5621
|
+
};
|
|
5110
5622
|
const EMPTY_CONTRIBUTION = {
|
|
5111
5623
|
anchorSeq: 0,
|
|
5112
5624
|
nodes: EMPTY_LIST,
|
|
@@ -5300,6 +5812,7 @@ window.__ModuleLoader__.load({
|
|
|
5300
5812
|
navigation = new MutableTurnNavigationIndex();
|
|
5301
5813
|
legacy = new LegacySliceBuilder();
|
|
5302
5814
|
referenceLabels = new ReferenceLabelProjector();
|
|
5815
|
+
skillNames = new SkillNameProjector();
|
|
5303
5816
|
order = EMPTY_KEYS;
|
|
5304
5817
|
/** Last published timeline: a Turn boundary can land without a new node. */
|
|
5305
5818
|
timeline = null;
|
|
@@ -5311,7 +5824,7 @@ window.__ModuleLoader__.load({
|
|
|
5311
5824
|
});
|
|
5312
5825
|
}
|
|
5313
5826
|
replace(input) {
|
|
5314
|
-
const nodes = this.referenceLabels.replace(input.nodes);
|
|
5827
|
+
const nodes = this.skillNames.replace(this.referenceLabels.replace(input.nodes));
|
|
5315
5828
|
this.store.replace(nodes);
|
|
5316
5829
|
this.order = orderedVisibleChatNodes(nodes).map((node) => node.key);
|
|
5317
5830
|
this.locations.rebuild(this.order, this.store);
|
|
@@ -5323,7 +5836,7 @@ window.__ModuleLoader__.load({
|
|
|
5323
5836
|
return snapshot;
|
|
5324
5837
|
}
|
|
5325
5838
|
apply(input) {
|
|
5326
|
-
const upserts = this.referenceLabels.apply(input.upserts, this.store);
|
|
5839
|
+
const upserts = this.skillNames.apply(this.referenceLabels.apply(input.upserts, this.store), this.store);
|
|
5327
5840
|
const processTurns = /* @__PURE__ */ new Set();
|
|
5328
5841
|
let structural = false;
|
|
5329
5842
|
const contentOnly = [];
|
|
@@ -5615,13 +6128,10 @@ window.__ModuleLoader__.load({
|
|
|
5615
6128
|
const unknownFallbackDefinition = {
|
|
5616
6129
|
kind: "unknown-surface",
|
|
5617
6130
|
target: "chat",
|
|
5618
|
-
match: (event) => {
|
|
5619
|
-
|
|
5620
|
-
|
|
5621
|
-
|
|
5622
|
-
role: "start"
|
|
5623
|
-
} : null;
|
|
5624
|
-
},
|
|
6131
|
+
match: (event) => event.type !== "assistant/live-chunk" && isAppendSurfaceEvent(event) ? {
|
|
6132
|
+
id: String(event.seq),
|
|
6133
|
+
role: "start"
|
|
6134
|
+
} : null,
|
|
5625
6135
|
start: (_context, match) => ({
|
|
5626
6136
|
kind: "unknown",
|
|
5627
6137
|
seq: match.event.seq,
|
|
@@ -6336,24 +6846,22 @@ window.__ModuleLoader__.load({
|
|
|
6336
6846
|
}
|
|
6337
6847
|
//#endregion
|
|
6338
6848
|
//#region lib/types/client/conversation-nodes/turn-process.js
|
|
6339
|
-
function isChunkRunEvent(event) {
|
|
6340
|
-
return event.type === "chunkrow/text-chunks" || event.type === "chunkrow/reasoning-chunks" || event.type === "chunkrow/tool-call-chunks";
|
|
6341
|
-
}
|
|
6342
6849
|
function eventTurn(event) {
|
|
6343
6850
|
const data = event.data;
|
|
6344
6851
|
return typeof data.turn === "number" ? data.turn : void 0;
|
|
6345
6852
|
}
|
|
6853
|
+
function visibleChunk(chunk) {
|
|
6854
|
+
if (chunk.type === "text-delta" || chunk.type === "reasoning-delta") return chunk.text.trim() !== "";
|
|
6855
|
+
if (chunk.type === "block-start") return chunk.blockType !== "text" && chunk.blockType !== "reasoning" && chunk.blockType !== "tool-call";
|
|
6856
|
+
if (chunk.type !== "block-end") return false;
|
|
6857
|
+
const block = chunk.block;
|
|
6858
|
+
if (block.type === "tool-call") return false;
|
|
6859
|
+
if (block.type === "text" || block.type === "reasoning") return block.text.trim() !== "";
|
|
6860
|
+
return true;
|
|
6861
|
+
}
|
|
6346
6862
|
function visibleAssistantEvent(event) {
|
|
6347
|
-
if (event.type === "assistant/chunk")
|
|
6348
|
-
|
|
6349
|
-
if (chunk.type === "text-delta" || chunk.type === "reasoning-delta") return chunk.text.trim() !== "";
|
|
6350
|
-
if (chunk.type === "block-start") return chunk.blockType !== "text" && chunk.blockType !== "reasoning" && chunk.blockType !== "tool-call";
|
|
6351
|
-
if (chunk.type !== "block-end") return false;
|
|
6352
|
-
const block = chunk.block;
|
|
6353
|
-
if (block.type === "tool-call") return false;
|
|
6354
|
-
if (block.type === "text" || block.type === "reasoning") return block.text.trim() !== "";
|
|
6355
|
-
return true;
|
|
6356
|
-
}
|
|
6863
|
+
if (event.type === "assistant/live-chunk") return visibleChunk(event.data.chunk);
|
|
6864
|
+
if (event.type === "assistant/attempt") return expandAssistantStream(event.data.stream).some((member) => visibleChunk(member.chunk));
|
|
6357
6865
|
return event.type === "assistant/message" && isAppendSurfaceEvent(event) && toAssistantBlocks(event.data.message.content).some((block) => {
|
|
6358
6866
|
if (block.kind === "tool-call") return false;
|
|
6359
6867
|
if (block.kind === "text" || block.kind === "reasoning") return block.text.trim() !== "";
|
|
@@ -6361,17 +6869,8 @@ window.__ModuleLoader__.load({
|
|
|
6361
6869
|
});
|
|
6362
6870
|
}
|
|
6363
6871
|
function processEvidence(event) {
|
|
6364
|
-
if (isChunkRunEvent(event)) {
|
|
6365
|
-
if (event.type === "chunkrow/tool-call-chunks") return void 0;
|
|
6366
|
-
const firstVisible = event.data.texts.findIndex((text) => text.trim() !== "");
|
|
6367
|
-
return firstVisible < 0 ? void 0 : {
|
|
6368
|
-
kind: "assistant",
|
|
6369
|
-
seq: event.seq + firstVisible,
|
|
6370
|
-
step: event.data.step
|
|
6371
|
-
};
|
|
6372
|
-
}
|
|
6373
6872
|
if (visibleAssistantEvent(event)) {
|
|
6374
|
-
if (event.type !== "assistant/chunk" && event.type !== "assistant/message") return void 0;
|
|
6873
|
+
if (event.type !== "assistant/live-chunk" && event.type !== "assistant/message" && event.type !== "assistant/attempt") return void 0;
|
|
6375
6874
|
return {
|
|
6376
6875
|
kind: "assistant",
|
|
6377
6876
|
seq: event.seq,
|
|
@@ -6486,7 +6985,7 @@ window.__ModuleLoader__.load({
|
|
|
6486
6985
|
};
|
|
6487
6986
|
const turn = eventTurn(event);
|
|
6488
6987
|
if (turn === void 0) return null;
|
|
6489
|
-
if (event.type === "assistant/chunk" || event.type === "assistant/message" ||
|
|
6988
|
+
if (event.type === "assistant/live-chunk" || event.type === "assistant/message" || event.type === "assistant/attempt" || event.type === "tool/call" || event.type === "tool/result" || event.type === "llm/retry" || event.type === "step/start" || event.type === "step/end" || event.type === "turn/end") return {
|
|
6490
6989
|
id: String(turn),
|
|
6491
6990
|
role: "update"
|
|
6492
6991
|
};
|
|
@@ -6505,8 +7004,7 @@ window.__ModuleLoader__.load({
|
|
|
6505
7004
|
},
|
|
6506
7005
|
update: (context, match) => updateProcessState(context.state, match.event),
|
|
6507
7006
|
publication: (match) => {
|
|
6508
|
-
if (
|
|
6509
|
-
if (match.event.type === "assistant/chunk") {
|
|
7007
|
+
if (match.event.type === "assistant/live-chunk") {
|
|
6510
7008
|
const type = match.event.data.chunk.type;
|
|
6511
7009
|
return type === "usage" || type === "finish" ? "none" : "animation-frame";
|
|
6512
7010
|
}
|
|
@@ -6568,6 +7066,11 @@ window.__ModuleLoader__.load({
|
|
|
6568
7066
|
model
|
|
6569
7067
|
} : void 0;
|
|
6570
7068
|
}
|
|
7069
|
+
function streamUsage(stream) {
|
|
7070
|
+
let sample;
|
|
7071
|
+
for (const member of expandAssistantStream(stream)) if (member.chunk.type === "usage") sample = member.chunk.usage;
|
|
7072
|
+
return sample;
|
|
7073
|
+
}
|
|
6571
7074
|
function normalizeUsage(usage, route) {
|
|
6572
7075
|
const { inputTokens, outputTokens, cacheReadTokens, cacheWriteTokens, reasoningTokens, totalTokens } = usage;
|
|
6573
7076
|
if (!isCount(inputTokens) || !isCount(outputTokens)) return void 0;
|
|
@@ -6695,16 +7198,20 @@ window.__ModuleLoader__.load({
|
|
|
6695
7198
|
};
|
|
6696
7199
|
continue;
|
|
6697
7200
|
}
|
|
6698
|
-
if (event.type === "assistant/
|
|
7201
|
+
if (event.type === "assistant/attempt") {
|
|
6699
7202
|
if (event.data.turn !== turn || state.kind !== "open" || !sameAttempt(state, event.data.turn, event.data.step)) {
|
|
6700
7203
|
invalid = true;
|
|
6701
7204
|
continue;
|
|
6702
7205
|
}
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
7206
|
+
let sample = state.sample;
|
|
7207
|
+
for (const member of expandAssistantStream(event.data.stream)) if (member.chunk.type === "usage") sample = member.chunk.usage;
|
|
7208
|
+
state = {
|
|
7209
|
+
kind: "open",
|
|
7210
|
+
turn,
|
|
7211
|
+
step: event.data.step,
|
|
7212
|
+
...sample === void 0 ? {} : { sample }
|
|
6706
7213
|
};
|
|
6707
|
-
|
|
7214
|
+
if (!closeOpen()) invalid = true;
|
|
6708
7215
|
else state = {
|
|
6709
7216
|
kind: "finishClosed",
|
|
6710
7217
|
turn,
|
|
@@ -6717,9 +7224,10 @@ window.__ModuleLoader__.load({
|
|
|
6717
7224
|
invalid = true;
|
|
6718
7225
|
continue;
|
|
6719
7226
|
}
|
|
6720
|
-
|
|
7227
|
+
const sample = event.data.usage ?? streamUsage(event.data.stream);
|
|
7228
|
+
if (sample !== void 0) state = {
|
|
6721
7229
|
...state,
|
|
6722
|
-
sample
|
|
7230
|
+
sample
|
|
6723
7231
|
};
|
|
6724
7232
|
if (!closeOpen(messageRoute(event.data.message))) invalid = true;
|
|
6725
7233
|
else state = {
|
|
@@ -6758,21 +7266,22 @@ window.__ModuleLoader__.load({
|
|
|
6758
7266
|
//#endregion
|
|
6759
7267
|
//#region lib/types/client/conversation-nodes/turn-tail.js
|
|
6760
7268
|
function isSessionEvent(event) {
|
|
6761
|
-
return event.type !== "
|
|
7269
|
+
return event.type !== "assistant/live-chunk";
|
|
6762
7270
|
}
|
|
6763
7271
|
function hasTextAssistant(event) {
|
|
6764
7272
|
return event.type === "assistant/message" && isAppendSurfaceEvent(event) && toAssistantBlocks(event.data.message.content).some((block) => block.kind === "text" && block.text.trim() !== "");
|
|
6765
7273
|
}
|
|
6766
|
-
function chunkHasText(
|
|
6767
|
-
if (event.type === "chunkrow/text-chunks") return event.data.texts.some((text) => text.trim() !== "");
|
|
6768
|
-
if (event.type === "chunkrow/reasoning-chunks" || event.type === "chunkrow/tool-call-chunks") return false;
|
|
6769
|
-
if (event.type !== "assistant/chunk") return false;
|
|
6770
|
-
const chunk = event.data.chunk;
|
|
7274
|
+
function chunkHasText(chunk) {
|
|
6771
7275
|
if (chunk.type === "text-delta") return chunk.text.trim() !== "";
|
|
6772
7276
|
return chunk.type === "block-end" && chunk.block.type === "text" && chunk.block.text.trim() !== "";
|
|
6773
7277
|
}
|
|
7278
|
+
function eventStreamHasText(event) {
|
|
7279
|
+
if (event.type === "assistant/live-chunk") return chunkHasText(event.data.chunk);
|
|
7280
|
+
if (event.type !== "assistant/attempt") return false;
|
|
7281
|
+
return expandAssistantStream(event.data.stream).some((member) => chunkHasText(member.chunk));
|
|
7282
|
+
}
|
|
6774
7283
|
function turnCoordinates(event) {
|
|
6775
|
-
if (event.type === "assistant/message" || event.type === "assistant/
|
|
7284
|
+
if (event.type === "assistant/message" || event.type === "assistant/attempt" || event.type === "assistant/live-chunk" || event.type === "step/start" || event.type === "step/end") return {
|
|
6776
7285
|
turn: event.data.turn,
|
|
6777
7286
|
step: event.data.step
|
|
6778
7287
|
};
|
|
@@ -6793,10 +7302,10 @@ window.__ModuleLoader__.load({
|
|
|
6793
7302
|
streamedText: false,
|
|
6794
7303
|
finalized: false
|
|
6795
7304
|
};
|
|
6796
|
-
if (event.type === "assistant/chunk" || event.type === "
|
|
7305
|
+
if (event.type === "assistant/live-chunk" || event.type === "assistant/attempt") {
|
|
6797
7306
|
steps.set(coordinates.step, {
|
|
6798
7307
|
...previous,
|
|
6799
|
-
streamedText: previous.streamedText ||
|
|
7308
|
+
streamedText: previous.streamedText || eventStreamHasText(event)
|
|
6800
7309
|
});
|
|
6801
7310
|
continue;
|
|
6802
7311
|
}
|