@tutti-os/agent-gui 0.0.104 → 0.0.105
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/dist/{AgentGUI-DQ9gVoXh.d.ts → AgentGUI-Do6py-T_.d.ts} +10 -5
- package/dist/AgentRichTextReadonly-F6PHC5SX.js +18 -0
- package/dist/AgentRichTextReadonly-F6PHC5SX.js.map +1 -0
- package/dist/agent-conversation/index.d.ts +3 -3
- package/dist/agent-conversation/index.js +11 -7
- package/dist/agent-conversation/index.js.map +1 -1
- package/dist/agent-gui.d.ts +4 -4
- package/dist/agent-gui.js +18 -14
- package/dist/agent-message-center/index.d.ts +1 -1
- package/dist/agent-message-center/index.js +13 -9
- package/dist/agent-message-center/index.js.map +1 -1
- package/dist/{agentConversationVM-CkcYM5Wg.d.ts → agentConversationVM-Bf3Zv3iI.d.ts} +9 -1
- package/dist/{agentFileMentionContracts-58IjMU-u.d.ts → agentFileMentionContracts-B70VnPWO.d.ts} +2 -0
- package/dist/{agentGuiNodeTypes-B9vcvjmR.d.ts → agentGuiNodeTypes-DbgQBiYz.d.ts} +4 -1
- package/dist/app/renderer/agentactivity.css +99 -0
- package/dist/{chunk-FJ4W2VC5.js → chunk-4ZWV57MF.js} +42 -10
- package/dist/chunk-4ZWV57MF.js.map +1 -0
- package/dist/{chunk-VAB7EIL5.js → chunk-6R7GHXRQ.js} +12 -6
- package/dist/chunk-6R7GHXRQ.js.map +1 -0
- package/dist/{chunk-TPV2SV6L.js → chunk-7MPN2JGL.js} +122 -154
- package/dist/chunk-7MPN2JGL.js.map +1 -0
- package/dist/{chunk-5X7YDOC6.js → chunk-D2JUDUYY.js} +1 -1
- package/dist/chunk-D2JUDUYY.js.map +1 -0
- package/dist/{chunk-HLVC4NNL.js → chunk-IR2CL2X2.js} +721 -1280
- package/dist/chunk-IR2CL2X2.js.map +1 -0
- package/dist/{chunk-NOXQOGT5.js → chunk-J2HG7UCP.js} +46 -22
- package/dist/chunk-J2HG7UCP.js.map +1 -0
- package/dist/{chunk-747L443E.js → chunk-JG7HGKZL.js} +595 -61
- package/dist/chunk-JG7HGKZL.js.map +1 -0
- package/dist/chunk-KPMQGPYU.js +43 -0
- package/dist/chunk-KPMQGPYU.js.map +1 -0
- package/dist/{chunk-OFSDOID4.js → chunk-LDZ6C3YV.js} +3 -39
- package/dist/chunk-LDZ6C3YV.js.map +1 -0
- package/dist/{chunk-7N524ZK7.js → chunk-N3HTEYLZ.js} +1308 -936
- package/dist/chunk-N3HTEYLZ.js.map +1 -0
- package/dist/{chunk-MUPZPISC.js → chunk-N4WVVCNI.js} +2 -2
- package/dist/{chunk-F5LFPORI.js → chunk-OWW7CU4U.js} +2 -2
- package/dist/chunk-SN6UYX54.js +42 -0
- package/dist/chunk-SN6UYX54.js.map +1 -0
- package/dist/{chunk-SKCLZXSW.js → chunk-TKBEVCHG.js} +5 -1
- package/dist/chunk-TKBEVCHG.js.map +1 -0
- package/dist/chunk-UFIEUC3Y.js +755 -0
- package/dist/chunk-UFIEUC3Y.js.map +1 -0
- package/dist/{chunk-AKKDP2LI.js → chunk-V5ROOS2O.js} +124 -2
- package/dist/chunk-V5ROOS2O.js.map +1 -0
- package/dist/chunk-XJ34OIEQ.js +18 -0
- package/dist/chunk-XJ34OIEQ.js.map +1 -0
- package/dist/{chunk-QI3JAO4J.js → chunk-ZSJBCZUH.js} +54 -7
- package/dist/chunk-ZSJBCZUH.js.map +1 -0
- package/dist/context-mention-palette/index.d.ts +1 -1
- package/dist/context-mention-palette/index.js +10 -8
- package/dist/{contribution-CTVBPN0R.d.ts → contribution-C6K5YfJ7.d.ts} +1 -0
- package/dist/custom-mention.d.ts +6 -0
- package/dist/custom-mention.js +1 -1
- package/dist/i18n/index.d.ts +4 -0
- package/dist/i18n/index.js +2 -2
- package/dist/index.d.ts +6 -6
- package/dist/index.js +18 -14
- package/dist/index.js.map +1 -1
- package/dist/mention-search.d.ts +42 -6
- package/dist/mention-search.js +8 -6
- package/dist/workbench/contribution.d.ts +1 -1
- package/dist/workbench/contribution.js +3 -3
- package/dist/workbench/index.d.ts +3 -2
- package/dist/workbench/index.js +3 -3
- package/dist/workbench/sessionTitle.js +2 -2
- package/package.json +12 -12
- package/dist/chunk-5X7YDOC6.js.map +0 -1
- package/dist/chunk-747L443E.js.map +0 -1
- package/dist/chunk-7N524ZK7.js.map +0 -1
- package/dist/chunk-AKKDP2LI.js.map +0 -1
- package/dist/chunk-FJ4W2VC5.js.map +0 -1
- package/dist/chunk-HLVC4NNL.js.map +0 -1
- package/dist/chunk-NOXQOGT5.js.map +0 -1
- package/dist/chunk-OFSDOID4.js.map +0 -1
- package/dist/chunk-QI3JAO4J.js.map +0 -1
- package/dist/chunk-SKCLZXSW.js.map +0 -1
- package/dist/chunk-TPV2SV6L.js.map +0 -1
- package/dist/chunk-VAB7EIL5.js.map +0 -1
- /package/dist/{chunk-MUPZPISC.js.map → chunk-N4WVVCNI.js.map} +0 -0
- /package/dist/{chunk-F5LFPORI.js.map → chunk-OWW7CU4U.js.map} +0 -0
|
@@ -0,0 +1,755 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AGENT_RICH_TEXT_CARET_ANCHOR,
|
|
3
|
+
attrsToMentionItem,
|
|
4
|
+
createAgentFileMentionExtension,
|
|
5
|
+
formatAgentMentionMarkdown,
|
|
6
|
+
mentionItemToAttrs,
|
|
7
|
+
parseAgentMentionMarkdown
|
|
8
|
+
} from "./chunk-J2HG7UCP.js";
|
|
9
|
+
import {
|
|
10
|
+
cn,
|
|
11
|
+
resolveAgentTargetPresentation,
|
|
12
|
+
useAgentTargetPresentations
|
|
13
|
+
} from "./chunk-KPMQGPYU.js";
|
|
14
|
+
|
|
15
|
+
// shared/AgentRichTextReadonly.tsx
|
|
16
|
+
import { useEffect } from "react";
|
|
17
|
+
import { EditorContent, useEditor } from "@tiptap/react";
|
|
18
|
+
|
|
19
|
+
// agent-gui/agentGuiNode/agentRichText/agentSkillTokenExtension.ts
|
|
20
|
+
import { mergeAttributes, Node } from "@tiptap/core";
|
|
21
|
+
|
|
22
|
+
// agent-gui/agentGuiNode/model/agentSkillOptions.ts
|
|
23
|
+
function skillTriggerForPrefix(skill, prefix) {
|
|
24
|
+
const trigger = skill.trigger.trim();
|
|
25
|
+
if (!trigger) {
|
|
26
|
+
return "";
|
|
27
|
+
}
|
|
28
|
+
if (prefix === void 0 || trigger.startsWith(prefix)) {
|
|
29
|
+
return trigger;
|
|
30
|
+
}
|
|
31
|
+
if (trigger.startsWith("$") || trigger.startsWith("/")) {
|
|
32
|
+
return `${prefix}${trigger.slice(1)}`;
|
|
33
|
+
}
|
|
34
|
+
return `${prefix}${trigger}`;
|
|
35
|
+
}
|
|
36
|
+
function labelForProviderSkill(skill, prefix) {
|
|
37
|
+
return stripSkillTriggerPrefix(skillTriggerForPrefix(skill, prefix));
|
|
38
|
+
}
|
|
39
|
+
function promptForProviderSkills(input) {
|
|
40
|
+
let prompt = input.prompt;
|
|
41
|
+
for (const skill of input.skills) {
|
|
42
|
+
if (!skill.invocation) {
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
const nativePrefix = skill.invocation === "promptItem" ? "$" : "/";
|
|
46
|
+
const nativeTrigger = skillTriggerForPrefix(skill, nativePrefix);
|
|
47
|
+
const aliasPrefix = nativePrefix === "$" ? "/" : "$";
|
|
48
|
+
const aliasTrigger = skillTriggerForPrefix(skill, aliasPrefix);
|
|
49
|
+
if (!nativeTrigger || !aliasTrigger || nativeTrigger === aliasTrigger) {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
prompt = replaceSkillTriggerToken(prompt, aliasTrigger, nativeTrigger);
|
|
53
|
+
}
|
|
54
|
+
return prompt;
|
|
55
|
+
}
|
|
56
|
+
function skillDescriptionForDisplay(description) {
|
|
57
|
+
const line = description?.split(/\r?\n/).map((part) => part.trim()).find((part) => part !== "");
|
|
58
|
+
return line || void 0;
|
|
59
|
+
}
|
|
60
|
+
function replaceSkillTriggerToken(prompt, from, to) {
|
|
61
|
+
return prompt.replace(
|
|
62
|
+
new RegExp(`(^|\\s)${escapeRegExp(from)}(?=$|\\s)`, "g"),
|
|
63
|
+
(_match, separator) => `${separator}${to}`
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function escapeRegExp(value) {
|
|
67
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
68
|
+
}
|
|
69
|
+
function stripSkillTriggerPrefix(trigger) {
|
|
70
|
+
if (trigger.startsWith("$") || trigger.startsWith("/")) {
|
|
71
|
+
return trigger.slice(1);
|
|
72
|
+
}
|
|
73
|
+
return trigger;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// agent-gui/agentGuiNode/agentRichText/agentSkillTokenExtension.ts
|
|
77
|
+
function createAgentSkillTokenExtension(options = {}) {
|
|
78
|
+
return Node.create({
|
|
79
|
+
name: "agentSkillToken",
|
|
80
|
+
group: "inline",
|
|
81
|
+
inline: true,
|
|
82
|
+
atom: true,
|
|
83
|
+
selectable: true,
|
|
84
|
+
addOptions() {
|
|
85
|
+
return options;
|
|
86
|
+
},
|
|
87
|
+
addAttributes() {
|
|
88
|
+
return {
|
|
89
|
+
label: { default: "" },
|
|
90
|
+
name: { default: "" },
|
|
91
|
+
trigger: { default: "" }
|
|
92
|
+
};
|
|
93
|
+
},
|
|
94
|
+
parseHTML() {
|
|
95
|
+
return [{ tag: "span[data-agent-skill-token]" }];
|
|
96
|
+
},
|
|
97
|
+
renderHTML({ HTMLAttributes }) {
|
|
98
|
+
const attrs = attrsToSkillTokenAttrs(HTMLAttributes);
|
|
99
|
+
const displayLabel = skillTokenDisplayLabel(attrs);
|
|
100
|
+
return [
|
|
101
|
+
"span",
|
|
102
|
+
mergeAttributes(HTMLAttributes, {
|
|
103
|
+
"aria-label": attrs.label,
|
|
104
|
+
contenteditable: "false",
|
|
105
|
+
"data-agent-skill-token": "true",
|
|
106
|
+
"data-agent-skill-trigger": attrs.trigger,
|
|
107
|
+
"data-agent-mention-kind": "skill",
|
|
108
|
+
class: "tsh-agent-object-token tsh-agent-object-token--entity"
|
|
109
|
+
}),
|
|
110
|
+
[
|
|
111
|
+
"span",
|
|
112
|
+
{
|
|
113
|
+
class: "tsh-agent-object-token__kind",
|
|
114
|
+
"aria-hidden": "true"
|
|
115
|
+
},
|
|
116
|
+
[
|
|
117
|
+
"span",
|
|
118
|
+
{
|
|
119
|
+
class: "tsh-agent-object-token__kind-icon",
|
|
120
|
+
"aria-hidden": "true"
|
|
121
|
+
},
|
|
122
|
+
""
|
|
123
|
+
]
|
|
124
|
+
],
|
|
125
|
+
["span", { class: "tsh-agent-object-token__main" }, displayLabel]
|
|
126
|
+
];
|
|
127
|
+
},
|
|
128
|
+
renderText({ node }) {
|
|
129
|
+
return attrsToSkillTokenAttrs(node.attrs ?? {}).trigger;
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
function parseAgentSkillToken(text, start, skills = []) {
|
|
134
|
+
if (!isSkillTokenBoundary(text[start - 1] ?? "")) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
for (const candidate of skillTokenCandidates(skills)) {
|
|
138
|
+
if (!text.startsWith(candidate.trigger, start)) {
|
|
139
|
+
continue;
|
|
140
|
+
}
|
|
141
|
+
const end = start + candidate.trigger.length;
|
|
142
|
+
if (!isSkillTokenBoundary(text[end] ?? "")) {
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
attrs: candidate,
|
|
147
|
+
end
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
152
|
+
function skillTokenCandidates(skills) {
|
|
153
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
154
|
+
for (const skill of skills) {
|
|
155
|
+
for (const prefix of ["$", "/"]) {
|
|
156
|
+
const trigger = skillTriggerForPrefix(skill, prefix);
|
|
157
|
+
if (!trigger || candidates.has(trigger)) {
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
candidates.set(trigger, {
|
|
161
|
+
label: labelForProviderSkill(skill, prefix),
|
|
162
|
+
name: skill.name.trim(),
|
|
163
|
+
trigger
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
return [...candidates.values()].sort(
|
|
168
|
+
(left, right) => right.trigger.length - left.trigger.length
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
function isSkillTokenBoundary(value) {
|
|
172
|
+
return value === "" || value === " " || value === "\n" || value === " ";
|
|
173
|
+
}
|
|
174
|
+
function attrsToSkillTokenAttrs(attrs) {
|
|
175
|
+
return {
|
|
176
|
+
label: typeof attrs.label === "string" ? attrs.label : "",
|
|
177
|
+
name: typeof attrs.name === "string" ? attrs.name : "",
|
|
178
|
+
trigger: typeof attrs.trigger === "string" ? attrs.trigger : ""
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
function skillTokenDisplayLabel(attrs) {
|
|
182
|
+
const label = attrs.label.trim() || attrs.trigger.trim();
|
|
183
|
+
if (!label || label.startsWith("/") || label.startsWith("$")) {
|
|
184
|
+
return label;
|
|
185
|
+
}
|
|
186
|
+
return `/${label}`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// agent-gui/agentGuiNode/agentRichText/agentCapabilityTokenExtension.ts
|
|
190
|
+
import { mergeAttributes as mergeAttributes2, Node as Node2 } from "@tiptap/core";
|
|
191
|
+
function createAgentCapabilityTokenExtension(options = {}) {
|
|
192
|
+
return Node2.create({
|
|
193
|
+
name: "agentCapabilityToken",
|
|
194
|
+
group: "inline",
|
|
195
|
+
inline: true,
|
|
196
|
+
atom: true,
|
|
197
|
+
selectable: true,
|
|
198
|
+
addOptions() {
|
|
199
|
+
return options;
|
|
200
|
+
},
|
|
201
|
+
addAttributes() {
|
|
202
|
+
return {
|
|
203
|
+
capability: { default: "" },
|
|
204
|
+
label: { default: "" },
|
|
205
|
+
name: { default: "" },
|
|
206
|
+
trigger: { default: "" }
|
|
207
|
+
};
|
|
208
|
+
},
|
|
209
|
+
parseHTML() {
|
|
210
|
+
return [{ tag: "span[data-agent-capability-token]" }];
|
|
211
|
+
},
|
|
212
|
+
renderHTML({ HTMLAttributes }) {
|
|
213
|
+
const attrs = attrsToCapabilityTokenAttrs(HTMLAttributes);
|
|
214
|
+
const displayLabel = capabilityTokenDisplayLabel(attrs);
|
|
215
|
+
return [
|
|
216
|
+
"span",
|
|
217
|
+
mergeAttributes2(HTMLAttributes, {
|
|
218
|
+
"aria-label": attrs.label,
|
|
219
|
+
contenteditable: "false",
|
|
220
|
+
"data-agent-capability-token": "true",
|
|
221
|
+
"data-agent-capability-trigger": attrs.trigger,
|
|
222
|
+
"data-agent-mention-kind": "capability",
|
|
223
|
+
class: "tsh-agent-object-token tsh-agent-object-token--entity"
|
|
224
|
+
}),
|
|
225
|
+
[
|
|
226
|
+
"span",
|
|
227
|
+
{
|
|
228
|
+
class: "tsh-agent-object-token__kind",
|
|
229
|
+
"aria-hidden": "true"
|
|
230
|
+
},
|
|
231
|
+
[
|
|
232
|
+
"span",
|
|
233
|
+
{
|
|
234
|
+
class: "tsh-agent-object-token__kind-icon",
|
|
235
|
+
"aria-hidden": "true"
|
|
236
|
+
},
|
|
237
|
+
""
|
|
238
|
+
]
|
|
239
|
+
],
|
|
240
|
+
["span", { class: "tsh-agent-object-token__main" }, displayLabel]
|
|
241
|
+
];
|
|
242
|
+
},
|
|
243
|
+
renderText({ node }) {
|
|
244
|
+
return attrsToCapabilityTokenAttrs(node.attrs ?? {}).trigger;
|
|
245
|
+
}
|
|
246
|
+
});
|
|
247
|
+
}
|
|
248
|
+
function parseAgentCapabilityToken(text, start, capabilities = []) {
|
|
249
|
+
if (!isCapabilityTokenBoundary(text[start - 1] ?? "")) {
|
|
250
|
+
return null;
|
|
251
|
+
}
|
|
252
|
+
for (const candidate of capabilityTokenCandidates(capabilities)) {
|
|
253
|
+
if (!text.startsWith(candidate.trigger, start)) {
|
|
254
|
+
continue;
|
|
255
|
+
}
|
|
256
|
+
const end = start + candidate.trigger.length;
|
|
257
|
+
if (!isCapabilityTokenBoundary(text[end] ?? "")) {
|
|
258
|
+
continue;
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
attrs: candidate,
|
|
262
|
+
end
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
return null;
|
|
266
|
+
}
|
|
267
|
+
function capabilityTokenCandidates(capabilities) {
|
|
268
|
+
const candidates = /* @__PURE__ */ new Map();
|
|
269
|
+
for (const capability of capabilities) {
|
|
270
|
+
const trigger = capability.trigger.trim();
|
|
271
|
+
if (!trigger || candidates.has(trigger)) {
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
candidates.set(trigger, {
|
|
275
|
+
capability: capability.capability.trim(),
|
|
276
|
+
label: capability.label.trim(),
|
|
277
|
+
name: capability.name.trim(),
|
|
278
|
+
trigger
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
return [...candidates.values()].sort(
|
|
282
|
+
(left, right) => right.trigger.length - left.trigger.length
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
function isCapabilityTokenBoundary(value) {
|
|
286
|
+
return value === "" || value === " " || value === "\n" || value === " ";
|
|
287
|
+
}
|
|
288
|
+
function attrsToCapabilityTokenAttrs(attrs) {
|
|
289
|
+
return {
|
|
290
|
+
capability: typeof attrs.capability === "string" ? attrs.capability : "",
|
|
291
|
+
label: typeof attrs.label === "string" ? attrs.label : "",
|
|
292
|
+
name: typeof attrs.name === "string" ? attrs.name : "",
|
|
293
|
+
trigger: typeof attrs.trigger === "string" ? attrs.trigger : ""
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
function capabilityTokenDisplayLabel(attrs) {
|
|
297
|
+
const label = attrs.label.trim() || attrs.trigger.trim();
|
|
298
|
+
if (!label || label.startsWith("/") || label.startsWith("$")) {
|
|
299
|
+
return label;
|
|
300
|
+
}
|
|
301
|
+
return `/${label}`;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
// agent-gui/agentGuiNode/agentRichText/agentRichTextDocument.ts
|
|
305
|
+
function createEmptyDocument() {
|
|
306
|
+
return {
|
|
307
|
+
type: "doc",
|
|
308
|
+
content: [{ type: "paragraph" }]
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
function isVisualLineStart(content) {
|
|
312
|
+
return content.length === 0 || content.at(-1)?.type === "hardBreak";
|
|
313
|
+
}
|
|
314
|
+
function createParagraphFromText(text, options = {}) {
|
|
315
|
+
const content = [];
|
|
316
|
+
let index = 0;
|
|
317
|
+
let textBuffer = "";
|
|
318
|
+
const flushTextBuffer = () => {
|
|
319
|
+
if (textBuffer.length === 0) {
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
content.push({ type: "text", text: textBuffer });
|
|
323
|
+
textBuffer = "";
|
|
324
|
+
};
|
|
325
|
+
while (index < text.length) {
|
|
326
|
+
const current = text[index];
|
|
327
|
+
if (current === "\n") {
|
|
328
|
+
flushTextBuffer();
|
|
329
|
+
content.push({ type: "hardBreak" });
|
|
330
|
+
index += 1;
|
|
331
|
+
continue;
|
|
332
|
+
}
|
|
333
|
+
const parsedMention = parseAgentMentionMarkdown(text, index);
|
|
334
|
+
if (parsedMention) {
|
|
335
|
+
flushTextBuffer();
|
|
336
|
+
if (isVisualLineStart(content)) {
|
|
337
|
+
content.push({ type: "text", text: AGENT_RICH_TEXT_CARET_ANCHOR });
|
|
338
|
+
}
|
|
339
|
+
content.push({
|
|
340
|
+
type: "agentFileMention",
|
|
341
|
+
// 转成规范 node attrs(如 workspace-reference 的 source/groupId/fileCount),
|
|
342
|
+
// 否则只读回显里的 reference chip 拿不到文件数 → 不显示「N 个文件」角标。
|
|
343
|
+
attrs: mentionItemToAttrs(parsedMention.item)
|
|
344
|
+
});
|
|
345
|
+
index = parsedMention.end;
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
const parsedCapabilityToken = parseAgentCapabilityToken(
|
|
349
|
+
text,
|
|
350
|
+
index,
|
|
351
|
+
options.capabilities
|
|
352
|
+
);
|
|
353
|
+
if (parsedCapabilityToken) {
|
|
354
|
+
flushTextBuffer();
|
|
355
|
+
content.push({
|
|
356
|
+
type: "agentCapabilityToken",
|
|
357
|
+
attrs: parsedCapabilityToken.attrs
|
|
358
|
+
});
|
|
359
|
+
index = parsedCapabilityToken.end;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
const parsedSkillToken = parseAgentSkillToken(text, index, options.skills);
|
|
363
|
+
if (parsedSkillToken) {
|
|
364
|
+
flushTextBuffer();
|
|
365
|
+
content.push({
|
|
366
|
+
type: "agentSkillToken",
|
|
367
|
+
attrs: parsedSkillToken.attrs
|
|
368
|
+
});
|
|
369
|
+
index = parsedSkillToken.end;
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
textBuffer += current;
|
|
373
|
+
index += 1;
|
|
374
|
+
}
|
|
375
|
+
flushTextBuffer();
|
|
376
|
+
return content.length > 0 ? { type: "paragraph", content } : { type: "paragraph" };
|
|
377
|
+
}
|
|
378
|
+
function plainTextToAgentRichTextDoc(text, options = {}) {
|
|
379
|
+
if (text.length === 0) {
|
|
380
|
+
return createEmptyDocument();
|
|
381
|
+
}
|
|
382
|
+
const normalized = text.replace(/\r\n?/g, "\n");
|
|
383
|
+
return {
|
|
384
|
+
type: "doc",
|
|
385
|
+
content: [createParagraphFromText(normalized, options)]
|
|
386
|
+
};
|
|
387
|
+
}
|
|
388
|
+
function plainTextToAgentRichTextInlineContent(text, options = {}) {
|
|
389
|
+
const paragraph = createParagraphFromText(
|
|
390
|
+
text.replace(/\r\n?/g, "\n"),
|
|
391
|
+
options
|
|
392
|
+
);
|
|
393
|
+
return paragraph.content ?? [];
|
|
394
|
+
}
|
|
395
|
+
function agentRichTextDocToPromptText(doc) {
|
|
396
|
+
if (doc.type !== "doc") {
|
|
397
|
+
return nodeToPromptText(doc);
|
|
398
|
+
}
|
|
399
|
+
return agentRichTextContentToPromptText(doc.content ?? []);
|
|
400
|
+
}
|
|
401
|
+
function editorToPromptText(editor) {
|
|
402
|
+
return agentRichTextDocToPromptText(editor.getJSON());
|
|
403
|
+
}
|
|
404
|
+
function agentRichTextContentToPromptText(content) {
|
|
405
|
+
if (content.length === 0) {
|
|
406
|
+
return "";
|
|
407
|
+
}
|
|
408
|
+
const separator = content.some((node) => isBlockPromptNode(node)) ? "\n" : "";
|
|
409
|
+
return content.map((node) => nodeToPromptText(node)).join(separator);
|
|
410
|
+
}
|
|
411
|
+
function isBlockPromptNode(node) {
|
|
412
|
+
return node.type === "doc" || node.type === "paragraph";
|
|
413
|
+
}
|
|
414
|
+
function nodeToPromptText(node) {
|
|
415
|
+
if (node.type === "text") {
|
|
416
|
+
return (node.text ?? "").replaceAll(AGENT_RICH_TEXT_CARET_ANCHOR, "");
|
|
417
|
+
}
|
|
418
|
+
if (node.type === "agentFileMention") {
|
|
419
|
+
return formatAgentMentionMarkdown(attrsToMentionItem(node.attrs ?? {}));
|
|
420
|
+
}
|
|
421
|
+
if (node.type === "agentSkillToken") {
|
|
422
|
+
return typeof node.attrs?.trigger === "string" ? node.attrs.trigger : "";
|
|
423
|
+
}
|
|
424
|
+
if (node.type === "agentCapabilityToken") {
|
|
425
|
+
return typeof node.attrs?.trigger === "string" ? node.attrs.trigger : "";
|
|
426
|
+
}
|
|
427
|
+
if (node.type === "hardBreak") {
|
|
428
|
+
return "\n";
|
|
429
|
+
}
|
|
430
|
+
if (!node.content || node.content.length === 0) {
|
|
431
|
+
return "";
|
|
432
|
+
}
|
|
433
|
+
return node.content.map((child) => nodeToPromptText(child)).join("");
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
// agent-gui/agentGuiNode/agentRichText/agentRichTextExtensions.ts
|
|
437
|
+
import { Extension } from "@tiptap/core";
|
|
438
|
+
import { NodeSelection, TextSelection } from "@tiptap/pm/state";
|
|
439
|
+
import { Plugin } from "@tiptap/pm/state";
|
|
440
|
+
import StarterKit from "@tiptap/starter-kit";
|
|
441
|
+
function createAgentPromptStarterKit() {
|
|
442
|
+
return StarterKit.configure({
|
|
443
|
+
blockquote: false,
|
|
444
|
+
bold: false,
|
|
445
|
+
bulletList: false,
|
|
446
|
+
code: false,
|
|
447
|
+
codeBlock: false,
|
|
448
|
+
dropcursor: false,
|
|
449
|
+
gapcursor: false,
|
|
450
|
+
heading: false,
|
|
451
|
+
horizontalRule: false,
|
|
452
|
+
italic: false,
|
|
453
|
+
link: false,
|
|
454
|
+
listItem: false,
|
|
455
|
+
listKeymap: false,
|
|
456
|
+
orderedList: false,
|
|
457
|
+
strike: false,
|
|
458
|
+
trailingNode: false,
|
|
459
|
+
underline: false
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
function createAgentTokenKeyboardExtension() {
|
|
463
|
+
return Extension.create({
|
|
464
|
+
name: "agentTokenKeyboard",
|
|
465
|
+
addProseMirrorPlugins() {
|
|
466
|
+
return [
|
|
467
|
+
new Plugin({
|
|
468
|
+
props: {
|
|
469
|
+
handleKeyDown(view, event) {
|
|
470
|
+
if (event.key !== "Backspace" && event.key !== "ArrowLeft") {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
const { doc, selection } = view.state;
|
|
474
|
+
if (selection instanceof NodeSelection && isSelectableAgentToken(selection.node)) {
|
|
475
|
+
event.preventDefault();
|
|
476
|
+
if (event.key === "ArrowLeft") {
|
|
477
|
+
view.dispatch(
|
|
478
|
+
view.state.tr.setSelection(
|
|
479
|
+
TextSelection.create(doc, selection.from)
|
|
480
|
+
)
|
|
481
|
+
);
|
|
482
|
+
} else {
|
|
483
|
+
view.dispatch(
|
|
484
|
+
view.state.tr.delete(selection.from, selection.to)
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
return true;
|
|
488
|
+
}
|
|
489
|
+
if (!selection.empty) {
|
|
490
|
+
return false;
|
|
491
|
+
}
|
|
492
|
+
const nodeBefore = selection.$from.nodeBefore;
|
|
493
|
+
if (!nodeBefore || !isSelectableAgentToken(nodeBefore)) {
|
|
494
|
+
return false;
|
|
495
|
+
}
|
|
496
|
+
event.preventDefault();
|
|
497
|
+
view.dispatch(
|
|
498
|
+
view.state.tr.setSelection(
|
|
499
|
+
NodeSelection.create(
|
|
500
|
+
doc,
|
|
501
|
+
selection.from - nodeBefore.nodeSize
|
|
502
|
+
)
|
|
503
|
+
)
|
|
504
|
+
);
|
|
505
|
+
return true;
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
})
|
|
509
|
+
];
|
|
510
|
+
}
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
function isSelectableAgentToken(node) {
|
|
514
|
+
return node?.type.name === "agentSkillToken" || node?.type.name === "agentCapabilityToken";
|
|
515
|
+
}
|
|
516
|
+
function createAgentRichTextInputExtensions(fileMentionOptions, skillTokenOptions, capabilityTokenOptions) {
|
|
517
|
+
return [
|
|
518
|
+
createAgentTokenKeyboardExtension(),
|
|
519
|
+
createAgentPromptStarterKit(),
|
|
520
|
+
createAgentFileMentionExtension(fileMentionOptions),
|
|
521
|
+
createAgentCapabilityTokenExtension(capabilityTokenOptions),
|
|
522
|
+
createAgentSkillTokenExtension(skillTokenOptions)
|
|
523
|
+
];
|
|
524
|
+
}
|
|
525
|
+
function createAgentRichTextReadonlyExtensions(skillTokenOptions, capabilityTokenOptions) {
|
|
526
|
+
return [
|
|
527
|
+
createAgentPromptStarterKit(),
|
|
528
|
+
createAgentFileMentionExtension({
|
|
529
|
+
enableSuggestions: false,
|
|
530
|
+
renderAsLink: true
|
|
531
|
+
}),
|
|
532
|
+
createAgentCapabilityTokenExtension(capabilityTokenOptions),
|
|
533
|
+
createAgentSkillTokenExtension(skillTokenOptions)
|
|
534
|
+
];
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// shared/AgentRichTextReadonly.tsx
|
|
538
|
+
import { jsx } from "react/jsx-runtime";
|
|
539
|
+
var EMPTY_WORKSPACE_APP_ICONS = [];
|
|
540
|
+
function AgentRichTextReadonly({
|
|
541
|
+
value,
|
|
542
|
+
className,
|
|
543
|
+
editorClassName,
|
|
544
|
+
onLinkClick,
|
|
545
|
+
availableSkills = [],
|
|
546
|
+
workspaceAppIcons = EMPTY_WORKSPACE_APP_ICONS,
|
|
547
|
+
agentTargets
|
|
548
|
+
}) {
|
|
549
|
+
"use memo";
|
|
550
|
+
const contextAgentTargets = useAgentTargetPresentations();
|
|
551
|
+
const effectiveAgentTargets = agentTargets ?? contextAgentTargets;
|
|
552
|
+
const contentDoc = plainTextToAgentRichTextDocWithMentionPresentations(
|
|
553
|
+
value,
|
|
554
|
+
availableSkills,
|
|
555
|
+
workspaceAppIcons,
|
|
556
|
+
effectiveAgentTargets
|
|
557
|
+
);
|
|
558
|
+
const isMentionOnly = isMentionOnlyRichTextDoc(contentDoc);
|
|
559
|
+
const editor = useEditor({
|
|
560
|
+
// AgentGUI is client-only. Deferring editor creation leaves every user
|
|
561
|
+
// message blank for one commit, then changes each transcript turn's
|
|
562
|
+
// measured height when TipTap mounts.
|
|
563
|
+
immediatelyRender: true,
|
|
564
|
+
editable: false,
|
|
565
|
+
extensions: createAgentRichTextReadonlyExtensions({
|
|
566
|
+
skills: availableSkills
|
|
567
|
+
}),
|
|
568
|
+
content: contentDoc,
|
|
569
|
+
editorProps: {
|
|
570
|
+
attributes: {
|
|
571
|
+
class: cn(
|
|
572
|
+
editorClassName,
|
|
573
|
+
"max-w-full overflow-x-hidden overflow-y-auto whitespace-pre-wrap break-words [overflow-wrap:anywhere] [&_p]:m-0 [&_p]:min-h-[1.45em] [&_a[data-agent-file-mention=true]]:cursor-pointer [&_[data-agent-file-mention=true]]:overflow-hidden"
|
|
574
|
+
)
|
|
575
|
+
},
|
|
576
|
+
handleDOMEvents: {
|
|
577
|
+
click: (_view, event) => {
|
|
578
|
+
if (!onLinkClick || !(event.target instanceof Element)) {
|
|
579
|
+
return false;
|
|
580
|
+
}
|
|
581
|
+
const mention = event.target.closest(
|
|
582
|
+
'[data-agent-file-mention="true"]'
|
|
583
|
+
);
|
|
584
|
+
if (!(mention instanceof HTMLElement)) {
|
|
585
|
+
return false;
|
|
586
|
+
}
|
|
587
|
+
const href = mention instanceof HTMLAnchorElement ? mention.getAttribute("href") || "" : mention.getAttribute("data-agent-mention-href") || "";
|
|
588
|
+
if (!href) {
|
|
589
|
+
return false;
|
|
590
|
+
}
|
|
591
|
+
event.preventDefault();
|
|
592
|
+
event.stopPropagation();
|
|
593
|
+
onLinkClick(href);
|
|
594
|
+
return true;
|
|
595
|
+
}
|
|
596
|
+
}
|
|
597
|
+
}
|
|
598
|
+
});
|
|
599
|
+
useEffect(() => {
|
|
600
|
+
if (!editor || editor.isDestroyed) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
603
|
+
const nextDoc = plainTextToAgentRichTextDocWithMentionPresentations(
|
|
604
|
+
value,
|
|
605
|
+
availableSkills,
|
|
606
|
+
workspaceAppIcons,
|
|
607
|
+
effectiveAgentTargets
|
|
608
|
+
);
|
|
609
|
+
if (JSON.stringify(editor.getJSON()) === JSON.stringify(nextDoc)) {
|
|
610
|
+
return;
|
|
611
|
+
}
|
|
612
|
+
editor.commands.setContent(nextDoc, { emitUpdate: false });
|
|
613
|
+
}, [
|
|
614
|
+
availableSkills,
|
|
615
|
+
effectiveAgentTargets,
|
|
616
|
+
editor,
|
|
617
|
+
value,
|
|
618
|
+
workspaceAppIcons
|
|
619
|
+
]);
|
|
620
|
+
if (!editor) {
|
|
621
|
+
return /* @__PURE__ */ jsx(
|
|
622
|
+
"div",
|
|
623
|
+
{
|
|
624
|
+
className,
|
|
625
|
+
"data-agent-mention-only": isMentionOnly ? "true" : void 0
|
|
626
|
+
}
|
|
627
|
+
);
|
|
628
|
+
}
|
|
629
|
+
return /* @__PURE__ */ jsx(
|
|
630
|
+
"div",
|
|
631
|
+
{
|
|
632
|
+
className,
|
|
633
|
+
"data-agent-mention-only": isMentionOnly ? "true" : void 0,
|
|
634
|
+
children: /* @__PURE__ */ jsx(EditorContent, { editor })
|
|
635
|
+
}
|
|
636
|
+
);
|
|
637
|
+
}
|
|
638
|
+
function isMentionOnlyRichTextDoc(doc) {
|
|
639
|
+
if (doc.type !== "doc") {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
const blocks = doc.content ?? [];
|
|
643
|
+
if (blocks.length !== 1) {
|
|
644
|
+
return false;
|
|
645
|
+
}
|
|
646
|
+
const paragraph = blocks[0];
|
|
647
|
+
if (paragraph?.type !== "paragraph") {
|
|
648
|
+
return false;
|
|
649
|
+
}
|
|
650
|
+
const inlineContent = (paragraph.content ?? []).filter(
|
|
651
|
+
(node) => !(node.type === "text" && (node.text ?? "").replaceAll(AGENT_RICH_TEXT_CARET_ANCHOR, "").length === 0)
|
|
652
|
+
);
|
|
653
|
+
return inlineContent.length === 1 && inlineContent[0]?.type === "agentFileMention";
|
|
654
|
+
}
|
|
655
|
+
function plainTextToAgentRichTextDocWithMentionPresentations(value, availableSkills, workspaceAppIcons, agentTargets) {
|
|
656
|
+
let doc = plainTextToAgentRichTextDoc(value, { skills: availableSkills });
|
|
657
|
+
if (workspaceAppIcons.length > 0) {
|
|
658
|
+
doc = hydrateWorkspaceAppMentionIcons(doc, workspaceAppIcons);
|
|
659
|
+
}
|
|
660
|
+
if (agentTargets.length > 0) {
|
|
661
|
+
doc = hydrateAgentTargetMentionPresentations(doc, agentTargets);
|
|
662
|
+
}
|
|
663
|
+
return doc;
|
|
664
|
+
}
|
|
665
|
+
function hydrateWorkspaceAppMentionIcons(node, workspaceAppIcons) {
|
|
666
|
+
const nextContent = node.content?.map(
|
|
667
|
+
(child) => hydrateWorkspaceAppMentionIcons(child, workspaceAppIcons)
|
|
668
|
+
);
|
|
669
|
+
if (node.type !== "agentFileMention") {
|
|
670
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
671
|
+
}
|
|
672
|
+
const attrs = node.attrs ?? {};
|
|
673
|
+
const kind = typeof attrs.kind === "string" ? attrs.kind : "";
|
|
674
|
+
const isWorkspaceAppMention = kind === "workspace-app";
|
|
675
|
+
const isAppWorkspaceReferenceMention = kind === "workspace-reference" && attrs.source === "app";
|
|
676
|
+
if (!isWorkspaceAppMention && !isAppWorkspaceReferenceMention) {
|
|
677
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
678
|
+
}
|
|
679
|
+
const workspaceId = typeof attrs.workspaceId === "string" ? attrs.workspaceId.trim() : "";
|
|
680
|
+
const appId = isWorkspaceAppMention && typeof attrs.appId === "string" ? attrs.appId.trim() : typeof attrs.targetId === "string" ? attrs.targetId.trim() : "";
|
|
681
|
+
const iconUrl = resolveWorkspaceAppIconUrl({
|
|
682
|
+
appId,
|
|
683
|
+
workspaceId,
|
|
684
|
+
workspaceAppIcons
|
|
685
|
+
});
|
|
686
|
+
if (!iconUrl) {
|
|
687
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
688
|
+
}
|
|
689
|
+
return {
|
|
690
|
+
...node,
|
|
691
|
+
attrs: {
|
|
692
|
+
...node.attrs,
|
|
693
|
+
iconUrl
|
|
694
|
+
},
|
|
695
|
+
...nextContent ? { content: nextContent } : {}
|
|
696
|
+
};
|
|
697
|
+
}
|
|
698
|
+
function resolveWorkspaceAppIconUrl(input) {
|
|
699
|
+
if (!input.appId) {
|
|
700
|
+
return void 0;
|
|
701
|
+
}
|
|
702
|
+
const exactMatch = input.workspaceAppIcons.find(
|
|
703
|
+
(icon) => icon.appId.trim() === input.appId && (icon.workspaceId?.trim() ?? "") === input.workspaceId && icon.iconUrl?.trim()
|
|
704
|
+
);
|
|
705
|
+
const fallbackMatch = input.workspaceAppIcons.find(
|
|
706
|
+
(icon) => icon.appId.trim() === input.appId && icon.iconUrl?.trim()
|
|
707
|
+
);
|
|
708
|
+
return exactMatch?.iconUrl?.trim() || fallbackMatch?.iconUrl?.trim() || void 0;
|
|
709
|
+
}
|
|
710
|
+
function hydrateAgentTargetMentionPresentations(node, agentTargets) {
|
|
711
|
+
const nextContent = node.content?.map(
|
|
712
|
+
(child) => hydrateAgentTargetMentionPresentations(child, agentTargets)
|
|
713
|
+
);
|
|
714
|
+
if (node.type !== "agentFileMention") {
|
|
715
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
716
|
+
}
|
|
717
|
+
const attrs = node.attrs ?? {};
|
|
718
|
+
if (attrs.kind !== "agent-target") {
|
|
719
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
720
|
+
}
|
|
721
|
+
const agentTargetId = typeof attrs.targetId === "string" ? attrs.targetId.trim() : "";
|
|
722
|
+
const workspaceId = typeof attrs.workspaceId === "string" ? attrs.workspaceId.trim() : "";
|
|
723
|
+
const target = resolveAgentTargetPresentation({
|
|
724
|
+
agentTargetId,
|
|
725
|
+
agentTargets,
|
|
726
|
+
workspaceId
|
|
727
|
+
});
|
|
728
|
+
if (!target) {
|
|
729
|
+
return nextContent ? { ...node, content: nextContent } : node;
|
|
730
|
+
}
|
|
731
|
+
return {
|
|
732
|
+
...node,
|
|
733
|
+
attrs: {
|
|
734
|
+
...node.attrs,
|
|
735
|
+
agentProviderId: target.provider?.trim() ?? "",
|
|
736
|
+
iconUrl: target.iconUrl?.trim() ?? "",
|
|
737
|
+
name: target.name?.trim() || attrs.name
|
|
738
|
+
},
|
|
739
|
+
...nextContent ? { content: nextContent } : {}
|
|
740
|
+
};
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
export {
|
|
744
|
+
skillTriggerForPrefix,
|
|
745
|
+
labelForProviderSkill,
|
|
746
|
+
promptForProviderSkills,
|
|
747
|
+
skillDescriptionForDisplay,
|
|
748
|
+
createAgentRichTextInputExtensions,
|
|
749
|
+
plainTextToAgentRichTextDoc,
|
|
750
|
+
plainTextToAgentRichTextInlineContent,
|
|
751
|
+
editorToPromptText,
|
|
752
|
+
agentRichTextContentToPromptText,
|
|
753
|
+
AgentRichTextReadonly
|
|
754
|
+
};
|
|
755
|
+
//# sourceMappingURL=chunk-UFIEUC3Y.js.map
|