ghostykit 0.6.4 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -19
- package/dist/chunks/{chunk-LPPND5ME.js → chunk-FWBUIGTC.js} +30 -145
- package/dist/chunks/chunk-UUH37KXA.js +144 -0
- package/dist/chunks/chunk-ZIUOXG7B.js +1757 -0
- package/dist/core/index.d.ts +1 -1
- package/dist/core/index.js +12 -8
- package/dist/core/narration.d.ts +18 -1
- package/dist/plugins/index.d.ts +39 -0
- package/dist/plugins/index.js +129 -0
- package/dist/react/Bubble.d.ts +11 -1
- package/dist/react/Composer.d.ts +11 -3
- package/dist/react/Piloto.d.ts +13 -37
- package/dist/react/context.d.ts +4 -1
- package/dist/react/index.d.ts +4 -3
- package/dist/react/index.js +503 -1788
- package/dist/react/plugins.d.ts +212 -0
- package/dist/react/usePilot.d.ts +15 -0
- package/dist/styles.css +572 -548
- package/package.json +5 -1
package/dist/react/index.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
import {
|
|
2
|
-
TOOL_VERBS_EN,
|
|
3
|
-
TOOL_VERBS_ES,
|
|
4
2
|
applyJsonPatch,
|
|
5
3
|
argsDetail,
|
|
6
4
|
beginSend,
|
|
@@ -9,10 +7,9 @@ import {
|
|
|
9
7
|
createPilotState,
|
|
10
8
|
dropLastExchange,
|
|
11
9
|
expiryMs,
|
|
10
|
+
extractBlocks,
|
|
12
11
|
extractReplyOptions,
|
|
13
|
-
groupSteps,
|
|
14
12
|
isNarration,
|
|
15
|
-
isRunning,
|
|
16
13
|
lastUserTurn,
|
|
17
14
|
markSubagent,
|
|
18
15
|
messagesToTurns,
|
|
@@ -23,20 +20,76 @@ import {
|
|
|
23
20
|
resolvePermission,
|
|
24
21
|
sendFailed,
|
|
25
22
|
splitNarration,
|
|
26
|
-
stepLabel,
|
|
27
23
|
stopTurn,
|
|
28
24
|
subagentsOf,
|
|
29
|
-
summarizeTools,
|
|
30
25
|
takeQueued,
|
|
31
|
-
toPermission
|
|
32
|
-
|
|
33
|
-
toolNames
|
|
34
|
-
} from "../chunks/chunk-LPPND5ME.js";
|
|
26
|
+
toPermission
|
|
27
|
+
} from "../chunks/chunk-FWBUIGTC.js";
|
|
35
28
|
import {
|
|
36
29
|
PilotHttpError,
|
|
37
30
|
createAgUiTransport,
|
|
38
31
|
readSse
|
|
39
32
|
} from "../chunks/chunk-TMEHQZWL.js";
|
|
33
|
+
import {
|
|
34
|
+
Activity,
|
|
35
|
+
AppWindow,
|
|
36
|
+
ArrowDown,
|
|
37
|
+
ArrowUpRight,
|
|
38
|
+
BUILTIN_CUSTOM,
|
|
39
|
+
BookOpen,
|
|
40
|
+
Check,
|
|
41
|
+
ChevronRight,
|
|
42
|
+
CircleCheck,
|
|
43
|
+
CircleSlash,
|
|
44
|
+
CircleX,
|
|
45
|
+
Clock,
|
|
46
|
+
Coins,
|
|
47
|
+
Composer,
|
|
48
|
+
Copy,
|
|
49
|
+
ExternalLink,
|
|
50
|
+
FilePenLine,
|
|
51
|
+
FileSpreadsheet,
|
|
52
|
+
FileText,
|
|
53
|
+
Folder,
|
|
54
|
+
Gauge,
|
|
55
|
+
Globe,
|
|
56
|
+
Image,
|
|
57
|
+
Inbox,
|
|
58
|
+
ListChecks,
|
|
59
|
+
LoaderCircle,
|
|
60
|
+
ModelPicker,
|
|
61
|
+
OctagonX,
|
|
62
|
+
PilotoContext,
|
|
63
|
+
ReferenceChips,
|
|
64
|
+
RotateCcw,
|
|
65
|
+
STRINGS_EN,
|
|
66
|
+
STRINGS_ES,
|
|
67
|
+
Search,
|
|
68
|
+
Send,
|
|
69
|
+
ShieldAlert,
|
|
70
|
+
Suggestions,
|
|
71
|
+
TurnContext,
|
|
72
|
+
UsersRound,
|
|
73
|
+
X,
|
|
74
|
+
definePlugin,
|
|
75
|
+
isDev,
|
|
76
|
+
mimeOf,
|
|
77
|
+
pluginPoints,
|
|
78
|
+
pluginRequires,
|
|
79
|
+
resolvePlugins,
|
|
80
|
+
rootProps,
|
|
81
|
+
usePiloto
|
|
82
|
+
} from "../chunks/chunk-ZIUOXG7B.js";
|
|
83
|
+
import {
|
|
84
|
+
TOOL_VERBS_EN,
|
|
85
|
+
TOOL_VERBS_ES,
|
|
86
|
+
groupSteps,
|
|
87
|
+
isRunning,
|
|
88
|
+
stepLabel,
|
|
89
|
+
summarizeTools,
|
|
90
|
+
toolName,
|
|
91
|
+
toolNames
|
|
92
|
+
} from "../chunks/chunk-UUH37KXA.js";
|
|
40
93
|
import {
|
|
41
94
|
applyReferences,
|
|
42
95
|
cleanUserText,
|
|
@@ -44,790 +97,16 @@ import {
|
|
|
44
97
|
systemNoteOf
|
|
45
98
|
} from "../chunks/chunk-6U545WJG.js";
|
|
46
99
|
|
|
47
|
-
// ../../node_modules/lucide-react/dist/esm/createLucideIcon.mjs
|
|
48
|
-
import { forwardRef as forwardRef2, createElement as createElement3 } from "react";
|
|
49
|
-
|
|
50
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/toKebabCase.mjs
|
|
51
|
-
var toKebabCase = (string) => string?.replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
|
|
52
|
-
|
|
53
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/toLucideIconData.mjs
|
|
54
|
-
function toLucideIconData(iconName, iconNode, aliases = []) {
|
|
55
|
-
if (iconNode == null) {
|
|
56
|
-
throw new Error("[lucide]: iconNode is required when icon name is used");
|
|
57
|
-
}
|
|
58
|
-
return {
|
|
59
|
-
name: toKebabCase(iconName),
|
|
60
|
-
size: 24,
|
|
61
|
-
node: iconNode,
|
|
62
|
-
...aliases.length > 0 ? { aliases } : {}
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/toCamelCase.mjs
|
|
67
|
-
var toCamelCase = (string) => {
|
|
68
|
-
let out = "";
|
|
69
|
-
let upperNext = false;
|
|
70
|
-
for (const ch of string) {
|
|
71
|
-
if (ch === "-" || ch === "_" || ch <= " ") {
|
|
72
|
-
upperNext = out.length > 0;
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (out.length === 0) {
|
|
76
|
-
out += ch.toLowerCase();
|
|
77
|
-
} else {
|
|
78
|
-
out += upperNext ? ch.toUpperCase() : ch;
|
|
79
|
-
}
|
|
80
|
-
upperNext = false;
|
|
81
|
-
}
|
|
82
|
-
return out;
|
|
83
|
-
};
|
|
84
|
-
|
|
85
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/toPascalCase.mjs
|
|
86
|
-
var toPascalCase = (string) => {
|
|
87
|
-
const camelCase = toCamelCase(string);
|
|
88
|
-
return camelCase.charAt(0).toUpperCase() + camelCase.slice(1);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
// ../../node_modules/lucide-react/dist/esm/Icon.mjs
|
|
92
|
-
import { forwardRef, createElement as createElement2 } from "react";
|
|
93
|
-
|
|
94
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/mergeClasses.mjs
|
|
95
|
-
var mergeClasses = (...classes) => classes.filter((className, index, array) => {
|
|
96
|
-
return Boolean(className) && className.trim() !== "" && array.indexOf(className) === index;
|
|
97
|
-
}).join(" ").trim();
|
|
98
|
-
|
|
99
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/build/defaultAttributes.mjs
|
|
100
|
-
var defaultAttributes = {
|
|
101
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
102
|
-
width: 24,
|
|
103
|
-
height: 24,
|
|
104
|
-
viewBox: "0 0 24 24",
|
|
105
|
-
fill: "none",
|
|
106
|
-
stroke: "currentColor",
|
|
107
|
-
"stroke-width": 2,
|
|
108
|
-
"stroke-linecap": "round",
|
|
109
|
-
"stroke-linejoin": "round"
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/build/buildLucideIconNode.mjs
|
|
113
|
-
function isDefined(value) {
|
|
114
|
-
return value !== null && value !== void 0;
|
|
115
|
-
}
|
|
116
|
-
function buildLucideIconNode(icon, params = {}) {
|
|
117
|
-
const attributeNames = params.attributeNames ?? {};
|
|
118
|
-
const getAttributeName = (attributeName) => attributeNames[attributeName] ?? attributeName;
|
|
119
|
-
const viewBoxWidth = icon.size ?? icon.width ?? defaultAttributes["width"];
|
|
120
|
-
const viewBoxHeight = icon.size ?? icon.height ?? defaultAttributes["height"];
|
|
121
|
-
const aliasClassNames = icon.aliases?.filter((alias) => typeof alias === "string" && alias.trim() !== "").map((alias) => `lucide-${alias}`) ?? [];
|
|
122
|
-
const iconClassNames = [...icon.name ? [`lucide-${icon.name}`] : [], ...aliasClassNames];
|
|
123
|
-
const classNamesFromClassName = params.className?.split(" ").filter(Boolean) ?? [];
|
|
124
|
-
const className = params.includeDefaultClasses === false ? mergeClasses(...classNamesFromClassName) : mergeClasses("lucide", ...iconClassNames, ...classNamesFromClassName);
|
|
125
|
-
const calculatedStrokeWidth = params.absoluteStrokeWidth ? Number(params.strokeWidth ?? defaultAttributes["stroke-width"]) * Number(icon.size ?? icon.width ?? defaultAttributes["width"]) / Number(params.size ?? params.width ?? defaultAttributes["width"]) : params.strokeWidth ?? defaultAttributes["stroke-width"];
|
|
126
|
-
const attributes = {
|
|
127
|
-
...Object.entries(defaultAttributes).reduce((attrs, [attrName, value]) => {
|
|
128
|
-
attrs[getAttributeName(attrName)] = value;
|
|
129
|
-
return attrs;
|
|
130
|
-
}, {}),
|
|
131
|
-
..."color" in params && params.color && {
|
|
132
|
-
[getAttributeName("stroke")]: params.color
|
|
133
|
-
},
|
|
134
|
-
..."size" in params && isDefined(params.size) && {
|
|
135
|
-
[getAttributeName("width")]: params.size,
|
|
136
|
-
[getAttributeName("height")]: params.size
|
|
137
|
-
},
|
|
138
|
-
..."width" in params && isDefined(params.width) && {
|
|
139
|
-
[getAttributeName("width")]: params.width
|
|
140
|
-
},
|
|
141
|
-
..."height" in params && isDefined(params.height) && {
|
|
142
|
-
[getAttributeName("height")]: params.height
|
|
143
|
-
},
|
|
144
|
-
[getAttributeName("stroke-width")]: calculatedStrokeWidth,
|
|
145
|
-
...className && {
|
|
146
|
-
[getAttributeName("class")]: className
|
|
147
|
-
},
|
|
148
|
-
[getAttributeName("viewBox")]: `0 0 ${viewBoxWidth} ${viewBoxHeight}`,
|
|
149
|
-
...params.hasA11yProp === false ? {
|
|
150
|
-
[getAttributeName("aria-hidden")]: "true"
|
|
151
|
-
} : {},
|
|
152
|
-
..."attributes" in params && params.attributes
|
|
153
|
-
};
|
|
154
|
-
return [
|
|
155
|
-
"svg",
|
|
156
|
-
attributes,
|
|
157
|
-
icon.node.map((child) => {
|
|
158
|
-
const [name, attrs, children] = child;
|
|
159
|
-
const nextAttrs = params.nonScalingStroke ? { [getAttributeName("vector-effect")]: "non-scaling-stroke", ...attrs } : attrs;
|
|
160
|
-
return children ? [name, nextAttrs, children] : [name, nextAttrs];
|
|
161
|
-
})
|
|
162
|
-
];
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/build/buildLucideIconForReact.mjs
|
|
166
|
-
function buildLucideIconForReact(icon, params = {}) {
|
|
167
|
-
return buildLucideIconNode(icon, {
|
|
168
|
-
...params,
|
|
169
|
-
attributeNames: {
|
|
170
|
-
...params.attributeNames,
|
|
171
|
-
class: "className",
|
|
172
|
-
"stroke-width": "strokeWidth",
|
|
173
|
-
"stroke-linecap": "strokeLinecap",
|
|
174
|
-
"stroke-linejoin": "strokeLinejoin",
|
|
175
|
-
"vector-effect": "vectorEffect"
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// ../../node_modules/lucide-react/dist/esm/shared/src/utils/hasA11yProp.mjs
|
|
181
|
-
var hasA11yProp = (props) => {
|
|
182
|
-
for (const prop in props) {
|
|
183
|
-
if (prop.startsWith("aria-") || prop === "role" || prop === "title") {
|
|
184
|
-
return true;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
return false;
|
|
188
|
-
};
|
|
189
|
-
|
|
190
|
-
// ../../node_modules/lucide-react/dist/esm/context.mjs
|
|
191
|
-
import { createContext, useContext, useMemo, createElement } from "react";
|
|
192
|
-
var LucideContext = createContext({});
|
|
193
|
-
var useLucideContext = () => useContext(LucideContext);
|
|
194
|
-
|
|
195
|
-
// ../../node_modules/lucide-react/dist/esm/Icon.mjs
|
|
196
|
-
var Icon = forwardRef(
|
|
197
|
-
({
|
|
198
|
-
color,
|
|
199
|
-
size,
|
|
200
|
-
width,
|
|
201
|
-
height,
|
|
202
|
-
strokeWidth,
|
|
203
|
-
absoluteStrokeWidth,
|
|
204
|
-
nonScalingStroke,
|
|
205
|
-
className = "",
|
|
206
|
-
children,
|
|
207
|
-
iconNode = [],
|
|
208
|
-
icon = {
|
|
209
|
-
node: iconNode,
|
|
210
|
-
aliases: [],
|
|
211
|
-
size: 24
|
|
212
|
-
},
|
|
213
|
-
...rest
|
|
214
|
-
}, ref) => {
|
|
215
|
-
const {
|
|
216
|
-
size: contextSize = 24,
|
|
217
|
-
strokeWidth: contextStrokeWidth = 2,
|
|
218
|
-
absoluteStrokeWidth: contextAbsoluteStrokeWidth = false,
|
|
219
|
-
nonScalingStroke: contextNonScalingStroke = false,
|
|
220
|
-
color: contextColor = "currentColor",
|
|
221
|
-
className: contextClass = ""
|
|
222
|
-
} = useLucideContext() ?? {};
|
|
223
|
-
const hasAccessibleProp = Boolean(children) || hasA11yProp(rest);
|
|
224
|
-
const [name, svgAttributes, builtIconNode = []] = buildLucideIconForReact(icon, {
|
|
225
|
-
color: color ?? contextColor,
|
|
226
|
-
width: width ?? size ?? contextSize,
|
|
227
|
-
height: height ?? size ?? contextSize,
|
|
228
|
-
strokeWidth: strokeWidth ?? contextStrokeWidth,
|
|
229
|
-
absoluteStrokeWidth: absoluteStrokeWidth ?? contextAbsoluteStrokeWidth,
|
|
230
|
-
nonScalingStroke: nonScalingStroke ?? contextNonScalingStroke,
|
|
231
|
-
className: mergeClasses(contextClass, className),
|
|
232
|
-
hasA11yProp: hasAccessibleProp,
|
|
233
|
-
attributes: rest
|
|
234
|
-
});
|
|
235
|
-
return createElement2(
|
|
236
|
-
name,
|
|
237
|
-
{
|
|
238
|
-
ref,
|
|
239
|
-
...svgAttributes
|
|
240
|
-
},
|
|
241
|
-
[
|
|
242
|
-
...builtIconNode.map(([tag, attrs]) => createElement2(tag, attrs)),
|
|
243
|
-
...Array.isArray(children) ? children : [children]
|
|
244
|
-
]
|
|
245
|
-
);
|
|
246
|
-
}
|
|
247
|
-
);
|
|
248
|
-
|
|
249
|
-
// ../../node_modules/lucide-react/dist/esm/createLucideIcon.mjs
|
|
250
|
-
function createLucideIcon(iconDataOrName, iconNode = [], aliases = []) {
|
|
251
|
-
const iconData = typeof iconDataOrName === "string" ? toLucideIconData(iconDataOrName, iconNode, aliases) : iconDataOrName;
|
|
252
|
-
const Component = forwardRef2(
|
|
253
|
-
({ className, ...props }, ref) => createElement3(Icon, {
|
|
254
|
-
ref,
|
|
255
|
-
icon: iconData,
|
|
256
|
-
className,
|
|
257
|
-
...props
|
|
258
|
-
})
|
|
259
|
-
);
|
|
260
|
-
if (iconData.name) {
|
|
261
|
-
Component.displayName = toPascalCase(iconData.name);
|
|
262
|
-
}
|
|
263
|
-
return Component;
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
// ../../node_modules/lucide-react/dist/esm/icons/activity.mjs
|
|
267
|
-
var __iconData = {
|
|
268
|
-
name: "activity",
|
|
269
|
-
size: 24,
|
|
270
|
-
node: [
|
|
271
|
-
[
|
|
272
|
-
"path",
|
|
273
|
-
{
|
|
274
|
-
d: "M22 12h-2.48a2 2 0 0 0-1.93 1.46l-2.35 8.36a.25.25 0 0 1-.48 0L9.24 2.18a.25.25 0 0 0-.48 0l-2.35 8.36A2 2 0 0 1 4.49 12H2",
|
|
275
|
-
key: "169zse"
|
|
276
|
-
}
|
|
277
|
-
]
|
|
278
|
-
]
|
|
279
|
-
};
|
|
280
|
-
__iconData.node;
|
|
281
|
-
var Activity = createLucideIcon(__iconData);
|
|
282
|
-
|
|
283
|
-
// ../../node_modules/lucide-react/dist/esm/icons/app-window.mjs
|
|
284
|
-
var __iconData2 = {
|
|
285
|
-
name: "app-window",
|
|
286
|
-
size: 24,
|
|
287
|
-
node: [
|
|
288
|
-
["rect", { x: "2", y: "4", width: "20", height: "16", rx: "2", key: "izxlao" }],
|
|
289
|
-
["path", { d: "M10 4v4", key: "pp8u80" }],
|
|
290
|
-
["path", { d: "M2 8h20", key: "d11cs7" }],
|
|
291
|
-
["path", { d: "M6 4v4", key: "1svtjw" }]
|
|
292
|
-
]
|
|
293
|
-
};
|
|
294
|
-
__iconData2.node;
|
|
295
|
-
var AppWindow = createLucideIcon(__iconData2);
|
|
296
|
-
|
|
297
|
-
// ../../node_modules/lucide-react/dist/esm/icons/arrow-down.mjs
|
|
298
|
-
var __iconData3 = {
|
|
299
|
-
name: "arrow-down",
|
|
300
|
-
size: 24,
|
|
301
|
-
node: [
|
|
302
|
-
["path", { d: "M12 5v14", key: "s699le" }],
|
|
303
|
-
["path", { d: "m19 12-7 7-7-7", key: "1idqje" }]
|
|
304
|
-
]
|
|
305
|
-
};
|
|
306
|
-
__iconData3.node;
|
|
307
|
-
var ArrowDown = createLucideIcon(__iconData3);
|
|
308
|
-
|
|
309
|
-
// ../../node_modules/lucide-react/dist/esm/icons/arrow-up-right.mjs
|
|
310
|
-
var __iconData4 = {
|
|
311
|
-
name: "arrow-up-right",
|
|
312
|
-
size: 24,
|
|
313
|
-
node: [
|
|
314
|
-
["path", { d: "M7 7h10v10", key: "1tivn9" }],
|
|
315
|
-
["path", { d: "M7 17 17 7", key: "1vkiza" }]
|
|
316
|
-
]
|
|
317
|
-
};
|
|
318
|
-
__iconData4.node;
|
|
319
|
-
var ArrowUpRight = createLucideIcon(__iconData4);
|
|
320
|
-
|
|
321
|
-
// ../../node_modules/lucide-react/dist/esm/icons/arrow-up.mjs
|
|
322
|
-
var __iconData5 = {
|
|
323
|
-
name: "arrow-up",
|
|
324
|
-
size: 24,
|
|
325
|
-
node: [
|
|
326
|
-
["path", { d: "m5 12 7-7 7 7", key: "hav0vg" }],
|
|
327
|
-
["path", { d: "M12 19V5", key: "x0mq9r" }]
|
|
328
|
-
]
|
|
329
|
-
};
|
|
330
|
-
__iconData5.node;
|
|
331
|
-
var ArrowUp = createLucideIcon(__iconData5);
|
|
332
|
-
|
|
333
|
-
// ../../node_modules/lucide-react/dist/esm/icons/book-open.mjs
|
|
334
|
-
var __iconData6 = {
|
|
335
|
-
name: "book-open",
|
|
336
|
-
size: 24,
|
|
337
|
-
node: [
|
|
338
|
-
["path", { d: "M12 5v16", key: "1f6ucr" }],
|
|
339
|
-
[
|
|
340
|
-
"path",
|
|
341
|
-
{
|
|
342
|
-
d: "M20.001 19A2 2 0 0022 17V5a2 2 0 00-1.999-2L16 3.002A5 5 0 0012 5a5 5 0 00-4-2H4a2 2 0 00-2 2v12a2 2 0 001.999 2H8a5 5 0 014 2 5 5 0 014-2z",
|
|
343
|
-
key: "1fyvmf"
|
|
344
|
-
}
|
|
345
|
-
]
|
|
346
|
-
]
|
|
347
|
-
};
|
|
348
|
-
__iconData6.node;
|
|
349
|
-
var BookOpen = createLucideIcon(__iconData6);
|
|
350
|
-
|
|
351
|
-
// ../../node_modules/lucide-react/dist/esm/icons/check.mjs
|
|
352
|
-
var __iconData7 = {
|
|
353
|
-
name: "check",
|
|
354
|
-
size: 24,
|
|
355
|
-
node: [["path", { d: "M20 6 9 17l-5-5", key: "1gmf2c" }]]
|
|
356
|
-
};
|
|
357
|
-
__iconData7.node;
|
|
358
|
-
var Check = createLucideIcon(__iconData7);
|
|
359
|
-
|
|
360
|
-
// ../../node_modules/lucide-react/dist/esm/icons/chevron-down.mjs
|
|
361
|
-
var __iconData8 = {
|
|
362
|
-
name: "chevron-down",
|
|
363
|
-
size: 24,
|
|
364
|
-
node: [["path", { d: "m6 9 6 6 6-6", key: "qrunsl" }]]
|
|
365
|
-
};
|
|
366
|
-
__iconData8.node;
|
|
367
|
-
var ChevronDown = createLucideIcon(__iconData8);
|
|
368
|
-
|
|
369
|
-
// ../../node_modules/lucide-react/dist/esm/icons/chevron-right.mjs
|
|
370
|
-
var __iconData9 = {
|
|
371
|
-
name: "chevron-right",
|
|
372
|
-
size: 24,
|
|
373
|
-
node: [["path", { d: "m9 18 6-6-6-6", key: "mthhwq" }]]
|
|
374
|
-
};
|
|
375
|
-
__iconData9.node;
|
|
376
|
-
var ChevronRight = createLucideIcon(__iconData9);
|
|
377
|
-
|
|
378
|
-
// ../../node_modules/lucide-react/dist/esm/icons/circle-check.mjs
|
|
379
|
-
var __iconData10 = {
|
|
380
|
-
name: "circle-check",
|
|
381
|
-
size: 24,
|
|
382
|
-
node: [
|
|
383
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
384
|
-
["path", { d: "m16 9-5.5 5.5L8 12", key: "xofnsj" }]
|
|
385
|
-
],
|
|
386
|
-
aliases: ["check-circle-2"]
|
|
387
|
-
};
|
|
388
|
-
__iconData10.node;
|
|
389
|
-
var CircleCheck = createLucideIcon(__iconData10);
|
|
390
|
-
|
|
391
|
-
// ../../node_modules/lucide-react/dist/esm/icons/circle-slash.mjs
|
|
392
|
-
var __iconData11 = {
|
|
393
|
-
name: "circle-slash",
|
|
394
|
-
size: 24,
|
|
395
|
-
node: [
|
|
396
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
397
|
-
["line", { x1: "9", x2: "15", y1: "15", y2: "9", key: "1dfufj" }]
|
|
398
|
-
]
|
|
399
|
-
};
|
|
400
|
-
__iconData11.node;
|
|
401
|
-
var CircleSlash = createLucideIcon(__iconData11);
|
|
402
|
-
|
|
403
|
-
// ../../node_modules/lucide-react/dist/esm/icons/circle-x.mjs
|
|
404
|
-
var __iconData12 = {
|
|
405
|
-
name: "circle-x",
|
|
406
|
-
size: 24,
|
|
407
|
-
node: [
|
|
408
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
409
|
-
["path", { d: "m15 9-6 6", key: "1uzhvr" }],
|
|
410
|
-
["path", { d: "m9 9 6 6", key: "z0biqf" }]
|
|
411
|
-
],
|
|
412
|
-
aliases: ["x-circle"]
|
|
413
|
-
};
|
|
414
|
-
__iconData12.node;
|
|
415
|
-
var CircleX = createLucideIcon(__iconData12);
|
|
416
|
-
|
|
417
|
-
// ../../node_modules/lucide-react/dist/esm/icons/clock.mjs
|
|
418
|
-
var __iconData13 = {
|
|
419
|
-
name: "clock",
|
|
420
|
-
size: 24,
|
|
421
|
-
node: [
|
|
422
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
423
|
-
["path", { d: "M12 6v6l4 2", key: "mmk7yg" }]
|
|
424
|
-
]
|
|
425
|
-
};
|
|
426
|
-
__iconData13.node;
|
|
427
|
-
var Clock = createLucideIcon(__iconData13);
|
|
428
|
-
|
|
429
|
-
// ../../node_modules/lucide-react/dist/esm/icons/coins.mjs
|
|
430
|
-
var __iconData14 = {
|
|
431
|
-
name: "coins",
|
|
432
|
-
size: 24,
|
|
433
|
-
node: [
|
|
434
|
-
["path", { d: "M13.744 17.736a6 6 0 1 1-7.48-7.48", key: "bq4yh3" }],
|
|
435
|
-
["path", { d: "M15 6h1v4", key: "11y1tn" }],
|
|
436
|
-
["path", { d: "m6.134 14.768.866-.5 2 3.464", key: "17snzx" }],
|
|
437
|
-
["circle", { cx: "16", cy: "8", r: "6", key: "14bfc9" }]
|
|
438
|
-
]
|
|
439
|
-
};
|
|
440
|
-
__iconData14.node;
|
|
441
|
-
var Coins = createLucideIcon(__iconData14);
|
|
442
|
-
|
|
443
|
-
// ../../node_modules/lucide-react/dist/esm/icons/copy.mjs
|
|
444
|
-
var __iconData15 = {
|
|
445
|
-
name: "copy",
|
|
446
|
-
size: 24,
|
|
447
|
-
node: [
|
|
448
|
-
["rect", { width: "14", height: "14", x: "8", y: "8", rx: "2", ry: "2", key: "17jyea" }],
|
|
449
|
-
["path", { d: "M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2", key: "zix9uf" }]
|
|
450
|
-
]
|
|
451
|
-
};
|
|
452
|
-
__iconData15.node;
|
|
453
|
-
var Copy = createLucideIcon(__iconData15);
|
|
454
|
-
|
|
455
|
-
// ../../node_modules/lucide-react/dist/esm/icons/cpu.mjs
|
|
456
|
-
var __iconData16 = {
|
|
457
|
-
name: "cpu",
|
|
458
|
-
size: 24,
|
|
459
|
-
node: [
|
|
460
|
-
["path", { d: "M12 20v2", key: "1lh1kg" }],
|
|
461
|
-
["path", { d: "M12 2v2", key: "tus03m" }],
|
|
462
|
-
["path", { d: "M17 20v2", key: "1rnc9c" }],
|
|
463
|
-
["path", { d: "M17 2v2", key: "11trls" }],
|
|
464
|
-
["path", { d: "M2 12h2", key: "1t8f8n" }],
|
|
465
|
-
["path", { d: "M2 17h2", key: "7oei6x" }],
|
|
466
|
-
["path", { d: "M2 7h2", key: "asdhe0" }],
|
|
467
|
-
["path", { d: "M20 12h2", key: "1q8mjw" }],
|
|
468
|
-
["path", { d: "M20 17h2", key: "1fpfkl" }],
|
|
469
|
-
["path", { d: "M20 7h2", key: "1o8tra" }],
|
|
470
|
-
["path", { d: "M7 20v2", key: "4gnj0m" }],
|
|
471
|
-
["path", { d: "M7 2v2", key: "1i4yhu" }],
|
|
472
|
-
["rect", { x: "4", y: "4", width: "16", height: "16", rx: "2", key: "1vbyd7" }],
|
|
473
|
-
["rect", { x: "8", y: "8", width: "8", height: "8", rx: "1", key: "z9xiuo" }]
|
|
474
|
-
]
|
|
475
|
-
};
|
|
476
|
-
__iconData16.node;
|
|
477
|
-
var Cpu = createLucideIcon(__iconData16);
|
|
478
|
-
|
|
479
|
-
// ../../node_modules/lucide-react/dist/esm/icons/crosshair.mjs
|
|
480
|
-
var __iconData17 = {
|
|
481
|
-
name: "crosshair",
|
|
482
|
-
size: 24,
|
|
483
|
-
node: [
|
|
484
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
485
|
-
["line", { x1: "22", x2: "18", y1: "12", y2: "12", key: "l9bcsi" }],
|
|
486
|
-
["line", { x1: "6", x2: "2", y1: "12", y2: "12", key: "13hhkx" }],
|
|
487
|
-
["line", { x1: "12", x2: "12", y1: "6", y2: "2", key: "10w3f3" }],
|
|
488
|
-
["line", { x1: "12", x2: "12", y1: "22", y2: "18", key: "15g9kq" }]
|
|
489
|
-
]
|
|
490
|
-
};
|
|
491
|
-
__iconData17.node;
|
|
492
|
-
var Crosshair = createLucideIcon(__iconData17);
|
|
493
|
-
|
|
494
|
-
// ../../node_modules/lucide-react/dist/esm/icons/external-link.mjs
|
|
495
|
-
var __iconData18 = {
|
|
496
|
-
name: "external-link",
|
|
497
|
-
size: 24,
|
|
498
|
-
node: [
|
|
499
|
-
["path", { d: "M15 3h6v6", key: "1q9fwt" }],
|
|
500
|
-
["path", { d: "M10 14 21 3", key: "gplh6r" }],
|
|
501
|
-
["path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6", key: "a6xqqp" }]
|
|
502
|
-
]
|
|
503
|
-
};
|
|
504
|
-
__iconData18.node;
|
|
505
|
-
var ExternalLink = createLucideIcon(__iconData18);
|
|
506
|
-
|
|
507
|
-
// ../../node_modules/lucide-react/dist/esm/icons/file-pen-line.mjs
|
|
508
|
-
var __iconData19 = {
|
|
509
|
-
name: "file-pen-line",
|
|
510
|
-
size: 24,
|
|
511
|
-
node: [
|
|
512
|
-
[
|
|
513
|
-
"path",
|
|
514
|
-
{
|
|
515
|
-
d: "M14.364 13.634a2 2 0 0 0-.506.854l-.837 2.87a.5.5 0 0 0 .62.62l2.87-.837a2 2 0 0 0 .854-.506l4.013-4.009a1 1 0 0 0-3.004-3.004z",
|
|
516
|
-
key: "ukzhwg"
|
|
517
|
-
}
|
|
518
|
-
],
|
|
519
|
-
["path", { d: "M14.487 7.858A1 1 0 0 1 14 7V2", key: "1klhew" }],
|
|
520
|
-
[
|
|
521
|
-
"path",
|
|
522
|
-
{
|
|
523
|
-
d: "M20 19.645V20a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l2.516 2.516",
|
|
524
|
-
key: "rxaxab"
|
|
525
|
-
}
|
|
526
|
-
],
|
|
527
|
-
["path", { d: "M8 18h1", key: "13wk12" }]
|
|
528
|
-
],
|
|
529
|
-
aliases: ["file-signature"]
|
|
530
|
-
};
|
|
531
|
-
__iconData19.node;
|
|
532
|
-
var FilePenLine = createLucideIcon(__iconData19);
|
|
533
|
-
|
|
534
|
-
// ../../node_modules/lucide-react/dist/esm/icons/file-spreadsheet.mjs
|
|
535
|
-
var __iconData20 = {
|
|
536
|
-
name: "file-spreadsheet",
|
|
537
|
-
size: 24,
|
|
538
|
-
node: [
|
|
539
|
-
[
|
|
540
|
-
"path",
|
|
541
|
-
{
|
|
542
|
-
d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
|
|
543
|
-
key: "1oefj6"
|
|
544
|
-
}
|
|
545
|
-
],
|
|
546
|
-
["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
|
|
547
|
-
["path", { d: "M8 13h2", key: "yr2amv" }],
|
|
548
|
-
["path", { d: "M14 13h2", key: "un5t4a" }],
|
|
549
|
-
["path", { d: "M8 17h2", key: "2yhykz" }],
|
|
550
|
-
["path", { d: "M14 17h2", key: "10kma7" }]
|
|
551
|
-
]
|
|
552
|
-
};
|
|
553
|
-
__iconData20.node;
|
|
554
|
-
var FileSpreadsheet = createLucideIcon(__iconData20);
|
|
555
|
-
|
|
556
|
-
// ../../node_modules/lucide-react/dist/esm/icons/file-text.mjs
|
|
557
|
-
var __iconData21 = {
|
|
558
|
-
name: "file-text",
|
|
559
|
-
size: 24,
|
|
560
|
-
node: [
|
|
561
|
-
[
|
|
562
|
-
"path",
|
|
563
|
-
{
|
|
564
|
-
d: "M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",
|
|
565
|
-
key: "1oefj6"
|
|
566
|
-
}
|
|
567
|
-
],
|
|
568
|
-
["path", { d: "M14 2v5a1 1 0 0 0 1 1h5", key: "wfsgrz" }],
|
|
569
|
-
["path", { d: "M10 9H8", key: "b1mrlr" }],
|
|
570
|
-
["path", { d: "M16 13H8", key: "t4e002" }],
|
|
571
|
-
["path", { d: "M16 17H8", key: "z1uh3a" }]
|
|
572
|
-
]
|
|
573
|
-
};
|
|
574
|
-
__iconData21.node;
|
|
575
|
-
var FileText = createLucideIcon(__iconData21);
|
|
576
|
-
|
|
577
|
-
// ../../node_modules/lucide-react/dist/esm/icons/folder.mjs
|
|
578
|
-
var __iconData22 = {
|
|
579
|
-
name: "folder",
|
|
580
|
-
size: 24,
|
|
581
|
-
node: [
|
|
582
|
-
[
|
|
583
|
-
"path",
|
|
584
|
-
{
|
|
585
|
-
d: "M20 20a2 2 0 0 0 2-2V8a2 2 0 0 0-2-2h-7.9a2 2 0 0 1-1.69-.9L9.6 3.9A2 2 0 0 0 7.93 3H4a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2Z",
|
|
586
|
-
key: "1kt360"
|
|
587
|
-
}
|
|
588
|
-
]
|
|
589
|
-
]
|
|
590
|
-
};
|
|
591
|
-
__iconData22.node;
|
|
592
|
-
var Folder = createLucideIcon(__iconData22);
|
|
593
|
-
|
|
594
|
-
// ../../node_modules/lucide-react/dist/esm/icons/gauge.mjs
|
|
595
|
-
var __iconData23 = {
|
|
596
|
-
name: "gauge",
|
|
597
|
-
size: 24,
|
|
598
|
-
node: [
|
|
599
|
-
["path", { d: "m12 14 4-4", key: "9kzdfg" }],
|
|
600
|
-
["path", { d: "M3.34 19a10 10 0 1 1 17.32 0", key: "19p75a" }]
|
|
601
|
-
]
|
|
602
|
-
};
|
|
603
|
-
__iconData23.node;
|
|
604
|
-
var Gauge = createLucideIcon(__iconData23);
|
|
605
|
-
|
|
606
|
-
// ../../node_modules/lucide-react/dist/esm/icons/globe.mjs
|
|
607
|
-
var __iconData24 = {
|
|
608
|
-
name: "globe",
|
|
609
|
-
size: 24,
|
|
610
|
-
node: [
|
|
611
|
-
["circle", { cx: "12", cy: "12", r: "10", key: "1mglay" }],
|
|
612
|
-
["path", { d: "M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20", key: "13o1zl" }],
|
|
613
|
-
["path", { d: "M2 12h20", key: "9i4pu4" }]
|
|
614
|
-
]
|
|
615
|
-
};
|
|
616
|
-
__iconData24.node;
|
|
617
|
-
var Globe = createLucideIcon(__iconData24);
|
|
618
|
-
|
|
619
|
-
// ../../node_modules/lucide-react/dist/esm/icons/image.mjs
|
|
620
|
-
var __iconData25 = {
|
|
621
|
-
name: "image",
|
|
622
|
-
size: 24,
|
|
623
|
-
node: [
|
|
624
|
-
["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", ry: "2", key: "1m3agn" }],
|
|
625
|
-
["circle", { cx: "9", cy: "9", r: "2", key: "af1f0g" }],
|
|
626
|
-
["path", { d: "m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21", key: "1xmnt7" }]
|
|
627
|
-
]
|
|
628
|
-
};
|
|
629
|
-
__iconData25.node;
|
|
630
|
-
var Image = createLucideIcon(__iconData25);
|
|
631
|
-
|
|
632
|
-
// ../../node_modules/lucide-react/dist/esm/icons/inbox.mjs
|
|
633
|
-
var __iconData26 = {
|
|
634
|
-
name: "inbox",
|
|
635
|
-
size: 24,
|
|
636
|
-
node: [
|
|
637
|
-
["polyline", { points: "22 12 16 12 14 15 10 15 8 12 2 12", key: "o97t9d" }],
|
|
638
|
-
[
|
|
639
|
-
"path",
|
|
640
|
-
{
|
|
641
|
-
d: "M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z",
|
|
642
|
-
key: "oot6mr"
|
|
643
|
-
}
|
|
644
|
-
]
|
|
645
|
-
]
|
|
646
|
-
};
|
|
647
|
-
__iconData26.node;
|
|
648
|
-
var Inbox = createLucideIcon(__iconData26);
|
|
649
|
-
|
|
650
|
-
// ../../node_modules/lucide-react/dist/esm/icons/list-checks.mjs
|
|
651
|
-
var __iconData27 = {
|
|
652
|
-
name: "list-checks",
|
|
653
|
-
size: 24,
|
|
654
|
-
node: [
|
|
655
|
-
["path", { d: "M13 5h8", key: "a7qcls" }],
|
|
656
|
-
["path", { d: "M13 12h8", key: "h98zly" }],
|
|
657
|
-
["path", { d: "M13 19h8", key: "c3s6r1" }],
|
|
658
|
-
["path", { d: "m3 17 2 2 4-4", key: "1jhpwq" }],
|
|
659
|
-
["path", { d: "m3 7 2 2 4-4", key: "1obspn" }]
|
|
660
|
-
]
|
|
661
|
-
};
|
|
662
|
-
__iconData27.node;
|
|
663
|
-
var ListChecks = createLucideIcon(__iconData27);
|
|
664
|
-
|
|
665
|
-
// ../../node_modules/lucide-react/dist/esm/icons/loader-circle.mjs
|
|
666
|
-
var __iconData28 = {
|
|
667
|
-
name: "loader-circle",
|
|
668
|
-
size: 24,
|
|
669
|
-
node: [["path", { d: "M21 12a9 9 0 1 1-6.219-8.56", key: "13zald" }]],
|
|
670
|
-
aliases: ["loader-2"]
|
|
671
|
-
};
|
|
672
|
-
__iconData28.node;
|
|
673
|
-
var LoaderCircle = createLucideIcon(__iconData28);
|
|
674
|
-
|
|
675
|
-
// ../../node_modules/lucide-react/dist/esm/icons/mic.mjs
|
|
676
|
-
var __iconData29 = {
|
|
677
|
-
name: "mic",
|
|
678
|
-
size: 24,
|
|
679
|
-
node: [
|
|
680
|
-
["path", { d: "M12 19v3", key: "npa21l" }],
|
|
681
|
-
["path", { d: "M19 10v2a7 7 0 0 1-14 0v-2", key: "1vc78b" }],
|
|
682
|
-
["rect", { x: "9", y: "2", width: "6", height: "13", rx: "3", key: "s6n7sd" }]
|
|
683
|
-
]
|
|
684
|
-
};
|
|
685
|
-
__iconData29.node;
|
|
686
|
-
var Mic = createLucideIcon(__iconData29);
|
|
687
|
-
|
|
688
|
-
// ../../node_modules/lucide-react/dist/esm/icons/octagon-x.mjs
|
|
689
|
-
var __iconData30 = {
|
|
690
|
-
name: "octagon-x",
|
|
691
|
-
size: 24,
|
|
692
|
-
node: [
|
|
693
|
-
["path", { d: "m15 9-6 6", key: "1uzhvr" }],
|
|
694
|
-
[
|
|
695
|
-
"path",
|
|
696
|
-
{
|
|
697
|
-
d: "M2.586 16.726A2 2 0 0 1 2 15.312V8.688a2 2 0 0 1 .586-1.414l4.688-4.688A2 2 0 0 1 8.688 2h6.624a2 2 0 0 1 1.414.586l4.688 4.688A2 2 0 0 1 22 8.688v6.624a2 2 0 0 1-.586 1.414l-4.688 4.688a2 2 0 0 1-1.414.586H8.688a2 2 0 0 1-1.414-.586z",
|
|
698
|
-
key: "2d38gg"
|
|
699
|
-
}
|
|
700
|
-
],
|
|
701
|
-
["path", { d: "m9 9 6 6", key: "z0biqf" }]
|
|
702
|
-
],
|
|
703
|
-
aliases: ["x-octagon"]
|
|
704
|
-
};
|
|
705
|
-
__iconData30.node;
|
|
706
|
-
var OctagonX = createLucideIcon(__iconData30);
|
|
707
|
-
|
|
708
|
-
// ../../node_modules/lucide-react/dist/esm/icons/paperclip.mjs
|
|
709
|
-
var __iconData31 = {
|
|
710
|
-
name: "paperclip",
|
|
711
|
-
size: 24,
|
|
712
|
-
node: [
|
|
713
|
-
[
|
|
714
|
-
"path",
|
|
715
|
-
{
|
|
716
|
-
d: "m16 6-8.414 8.586a2 2 0 0 0 2.829 2.829l8.414-8.586a4 4 0 1 0-5.657-5.657l-8.379 8.551a6 6 0 1 0 8.485 8.485l8.379-8.551",
|
|
717
|
-
key: "1miecu"
|
|
718
|
-
}
|
|
719
|
-
]
|
|
720
|
-
]
|
|
721
|
-
};
|
|
722
|
-
__iconData31.node;
|
|
723
|
-
var Paperclip = createLucideIcon(__iconData31);
|
|
724
|
-
|
|
725
|
-
// ../../node_modules/lucide-react/dist/esm/icons/rotate-ccw.mjs
|
|
726
|
-
var __iconData32 = {
|
|
727
|
-
name: "rotate-ccw",
|
|
728
|
-
size: 24,
|
|
729
|
-
node: [
|
|
730
|
-
["path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8", key: "1357e3" }],
|
|
731
|
-
["path", { d: "M3 3v5h5", key: "1xhq8a" }]
|
|
732
|
-
]
|
|
733
|
-
};
|
|
734
|
-
__iconData32.node;
|
|
735
|
-
var RotateCcw = createLucideIcon(__iconData32);
|
|
736
|
-
|
|
737
|
-
// ../../node_modules/lucide-react/dist/esm/icons/search.mjs
|
|
738
|
-
var __iconData33 = {
|
|
739
|
-
name: "search",
|
|
740
|
-
size: 24,
|
|
741
|
-
node: [
|
|
742
|
-
["path", { d: "m21 21-4.34-4.34", key: "14j7rj" }],
|
|
743
|
-
["circle", { cx: "11", cy: "11", r: "8", key: "4ej97u" }]
|
|
744
|
-
]
|
|
745
|
-
};
|
|
746
|
-
__iconData33.node;
|
|
747
|
-
var Search = createLucideIcon(__iconData33);
|
|
748
|
-
|
|
749
|
-
// ../../node_modules/lucide-react/dist/esm/icons/send.mjs
|
|
750
|
-
var __iconData34 = {
|
|
751
|
-
name: "send",
|
|
752
|
-
size: 24,
|
|
753
|
-
node: [
|
|
754
|
-
[
|
|
755
|
-
"path",
|
|
756
|
-
{
|
|
757
|
-
d: "M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z",
|
|
758
|
-
key: "1ffxy3"
|
|
759
|
-
}
|
|
760
|
-
],
|
|
761
|
-
["path", { d: "m21.854 2.147-10.94 10.939", key: "12cjpa" }]
|
|
762
|
-
]
|
|
763
|
-
};
|
|
764
|
-
__iconData34.node;
|
|
765
|
-
var Send = createLucideIcon(__iconData34);
|
|
766
|
-
|
|
767
|
-
// ../../node_modules/lucide-react/dist/esm/icons/shield-alert.mjs
|
|
768
|
-
var __iconData35 = {
|
|
769
|
-
name: "shield-alert",
|
|
770
|
-
size: 24,
|
|
771
|
-
node: [
|
|
772
|
-
[
|
|
773
|
-
"path",
|
|
774
|
-
{
|
|
775
|
-
d: "M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",
|
|
776
|
-
key: "oel41y"
|
|
777
|
-
}
|
|
778
|
-
],
|
|
779
|
-
["path", { d: "M12 8v4", key: "1got3b" }],
|
|
780
|
-
["path", { d: "M12 16h.01", key: "1drbdi" }]
|
|
781
|
-
]
|
|
782
|
-
};
|
|
783
|
-
__iconData35.node;
|
|
784
|
-
var ShieldAlert = createLucideIcon(__iconData35);
|
|
785
|
-
|
|
786
|
-
// ../../node_modules/lucide-react/dist/esm/icons/square.mjs
|
|
787
|
-
var __iconData36 = {
|
|
788
|
-
name: "square",
|
|
789
|
-
size: 24,
|
|
790
|
-
node: [["rect", { width: "18", height: "18", x: "3", y: "3", rx: "2", key: "afitv7" }]]
|
|
791
|
-
};
|
|
792
|
-
__iconData36.node;
|
|
793
|
-
var Square = createLucideIcon(__iconData36);
|
|
794
|
-
|
|
795
|
-
// ../../node_modules/lucide-react/dist/esm/icons/users-round.mjs
|
|
796
|
-
var __iconData37 = {
|
|
797
|
-
name: "users-round",
|
|
798
|
-
size: 24,
|
|
799
|
-
node: [
|
|
800
|
-
["path", { d: "M18 21a8 8 0 0 0-16 0", key: "3ypg7q" }],
|
|
801
|
-
["circle", { cx: "10", cy: "8", r: "5", key: "o932ke" }],
|
|
802
|
-
["path", { d: "M22 20c0-3.37-2-6.5-4-8a5 5 0 0 0-.45-8.3", key: "10s06x" }]
|
|
803
|
-
],
|
|
804
|
-
aliases: ["users-2"]
|
|
805
|
-
};
|
|
806
|
-
__iconData37.node;
|
|
807
|
-
var UsersRound = createLucideIcon(__iconData37);
|
|
808
|
-
|
|
809
|
-
// ../../node_modules/lucide-react/dist/esm/icons/x.mjs
|
|
810
|
-
var __iconData38 = {
|
|
811
|
-
name: "x",
|
|
812
|
-
size: 24,
|
|
813
|
-
node: [
|
|
814
|
-
["path", { d: "M18 6 6 18", key: "1bl5f8" }],
|
|
815
|
-
["path", { d: "m6 6 12 12", key: "d8bk6v" }]
|
|
816
|
-
]
|
|
817
|
-
};
|
|
818
|
-
__iconData38.node;
|
|
819
|
-
var X = createLucideIcon(__iconData38);
|
|
820
|
-
|
|
821
100
|
// src/react/Piloto.tsx
|
|
822
101
|
import {
|
|
823
|
-
forwardRef
|
|
824
|
-
useCallback as
|
|
825
|
-
useEffect as
|
|
102
|
+
forwardRef,
|
|
103
|
+
useCallback as useCallback2,
|
|
104
|
+
useEffect as useEffect5,
|
|
826
105
|
useImperativeHandle,
|
|
827
106
|
useLayoutEffect,
|
|
828
|
-
useMemo as
|
|
829
|
-
useRef as
|
|
830
|
-
useState as
|
|
107
|
+
useMemo as useMemo3,
|
|
108
|
+
useRef as useRef4,
|
|
109
|
+
useState as useState8
|
|
831
110
|
} from "react";
|
|
832
111
|
|
|
833
112
|
// src/react/Bubble.tsx
|
|
@@ -835,184 +114,6 @@ import { useState as useState5 } from "react";
|
|
|
835
114
|
|
|
836
115
|
// src/react/ConfirmCard.tsx
|
|
837
116
|
import { useEffect, useRef, useState } from "react";
|
|
838
|
-
|
|
839
|
-
// src/react/context.tsx
|
|
840
|
-
import { createContext as createContext2, useContext as useContext2 } from "react";
|
|
841
|
-
|
|
842
|
-
// src/react/strings.ts
|
|
843
|
-
var STRINGS_ES = {
|
|
844
|
-
numberLocale: "es-MX",
|
|
845
|
-
placeholder: (agent) => `Escr\xEDbele a ${agent}`,
|
|
846
|
-
placeholderDefault: "Escr\xEDbele al agente",
|
|
847
|
-
send: "Enviar",
|
|
848
|
-
stop: "Detener",
|
|
849
|
-
uploading: "Subiendo tu archivo\u2026",
|
|
850
|
-
uploadingN: (n) => `Subiendo tus ${n} archivos\u2026`,
|
|
851
|
-
attachImage: "Adjuntar imagen",
|
|
852
|
-
attachFile: "Adjuntar archivo",
|
|
853
|
-
noImages: "Este agente no ve im\xE1genes",
|
|
854
|
-
removeAttachment: "Quitar adjunto",
|
|
855
|
-
removeReference: "Quitar referencia",
|
|
856
|
-
dropFiles: "Suelta tus archivos",
|
|
857
|
-
dropHint: "Excel, Word, PDF o im\xE1genes",
|
|
858
|
-
tooBig: (name, mb) => `${name} pesa m\xE1s de ${mb} MB`,
|
|
859
|
-
tooMany: (max) => `no caben m\xE1s de ${max} archivos por mensaje`,
|
|
860
|
-
cantSeeImage: (name) => `${name}: este agente no ve im\xE1genes`,
|
|
861
|
-
cantUpload: (name) => `${name}: aqu\xED s\xF3lo se pueden mandar im\xE1genes y texto`,
|
|
862
|
-
uploadFailed: "no se pudo subir el archivo",
|
|
863
|
-
recordVoice: "Grabar nota de voz",
|
|
864
|
-
voiceNote: "Nota de voz",
|
|
865
|
-
cancelVoice: "Cancelar la nota de voz",
|
|
866
|
-
stopAndSendVoice: "Parar y mandar la nota de voz",
|
|
867
|
-
micDenied: "No tengo permiso para usar el micr\xF3fono.",
|
|
868
|
-
voiceEmpty: "no se entendi\xF3 nada en la nota de voz",
|
|
869
|
-
voiceFailed: "no se pudo mandar la nota de voz",
|
|
870
|
-
model: "Modelo",
|
|
871
|
-
thinking: "Pensando\u2026",
|
|
872
|
-
howItGoes: (s) => s < 6 ? "Pensando\u2026" : s < 15 ? "Trabajando\u2026" : s < 60 ? "Estoy en ello\u2026" : s < 120 ? "Esto me lleva un poco\u2026" : s < 300 ? "Llevo un buen rato\u2026" : "Me est\xE1 tomando mucho \u2014 puedes detenerme",
|
|
873
|
-
stillWorking: "Estoy en ello\u2026",
|
|
874
|
-
retry: "Reintentar",
|
|
875
|
-
copy: "Copiar",
|
|
876
|
-
copied: "Copiado",
|
|
877
|
-
copyMessage: "Copiar mensaje",
|
|
878
|
-
worked: (s) => `Trabaj\xF3 ${s} s`,
|
|
879
|
-
stepsExpand: "Ver el detalle de los pasos",
|
|
880
|
-
stepsCollapse: "Plegar los pasos",
|
|
881
|
-
earlierSteps: (n) => n === 1 ? "1 paso antes" : `${n} pasos antes`,
|
|
882
|
-
withProblems: (n) => n === 1 ? "1 con problemas" : `${n} con problemas`,
|
|
883
|
-
running: "Ejecutando",
|
|
884
|
-
done: "Lista",
|
|
885
|
-
failed: "Fall\xF3",
|
|
886
|
-
step: "Paso",
|
|
887
|
-
replyOptions: "Opciones para responder",
|
|
888
|
-
linkTitle: "Vas a salir de aqu\xED",
|
|
889
|
-
linkCopy: "Copiar",
|
|
890
|
-
linkCopied: "Copiado",
|
|
891
|
-
linkOpen: "Abrir",
|
|
892
|
-
close: "Cerrar",
|
|
893
|
-
goToLatest: "Ir al \xFAltimo mensaje",
|
|
894
|
-
steps: { waking: "Despertando al agente\u2026", session: "Preparando la sesi\xF3n\u2026", compacting: "Resumiendo la conversaci\xF3n\u2026" },
|
|
895
|
-
loadOlder: "Cargar mensajes anteriores",
|
|
896
|
-
loadingOlder: "Cargando\u2026",
|
|
897
|
-
continueRun: "Continuar",
|
|
898
|
-
runCut: "La respuesta se cort\xF3 antes de terminar.",
|
|
899
|
-
stalled: "Se ator\xF3, sigo intentando\u2026",
|
|
900
|
-
truncated: "La respuesta qued\xF3 incompleta.",
|
|
901
|
-
attachmentFailed: (name, reason) => reason ? `No pude leer ${name}: ${reason}` : `No pude leer ${name}`,
|
|
902
|
-
queued: "Se manda cuando termine",
|
|
903
|
-
subagentsWorking: (n) => n === 1 ? "1 agente trabajando" : `${n} agentes trabajando`,
|
|
904
|
-
subagentsDone: (n) => n === 1 ? "1 agente termin\xF3" : `${n} agentes terminaron`,
|
|
905
|
-
subagentStop: "Detener",
|
|
906
|
-
subagentStatus: { running: "Trabajando", completed: "Termin\xF3", failed: "Fall\xF3", stopped: "Detenido" },
|
|
907
|
-
confirmTitle: "Necesito tu permiso para",
|
|
908
|
-
approve: "Aprobar",
|
|
909
|
-
reject: "Rechazar",
|
|
910
|
-
expiresIn: (t) => `Vence en ${t}`,
|
|
911
|
-
expiredNow: "Venci\xF3 sin respuesta",
|
|
912
|
-
decisionApproved: "Aprobaste",
|
|
913
|
-
decisionRejected: "Rechazaste",
|
|
914
|
-
decisionExpired: "Venci\xF3",
|
|
915
|
-
decisionCancelled: "Descartaste",
|
|
916
|
-
stampCancelled: "Descartado",
|
|
917
|
-
stampApproved: "Aprobado",
|
|
918
|
-
stampRejected: "Rechazado",
|
|
919
|
-
stampExpired: "Vencido"
|
|
920
|
-
};
|
|
921
|
-
var STRINGS_EN = {
|
|
922
|
-
numberLocale: "en-US",
|
|
923
|
-
placeholder: (agent) => `Message ${agent}`,
|
|
924
|
-
placeholderDefault: "Message the agent",
|
|
925
|
-
send: "Send",
|
|
926
|
-
stop: "Stop",
|
|
927
|
-
uploading: "Uploading your file\u2026",
|
|
928
|
-
uploadingN: (n) => `Uploading your ${n} files\u2026`,
|
|
929
|
-
attachImage: "Attach image",
|
|
930
|
-
attachFile: "Attach file",
|
|
931
|
-
noImages: "This agent can't see images",
|
|
932
|
-
removeAttachment: "Remove attachment",
|
|
933
|
-
removeReference: "Remove reference",
|
|
934
|
-
dropFiles: "Drop your files",
|
|
935
|
-
dropHint: "Excel, Word, PDF or images",
|
|
936
|
-
tooBig: (name, mb) => `${name} is larger than ${mb} MB`,
|
|
937
|
-
tooMany: (max) => `no more than ${max} files per message`,
|
|
938
|
-
cantSeeImage: (name) => `${name}: this agent can't see images`,
|
|
939
|
-
cantUpload: (name) => `${name}: only images and text can be sent here`,
|
|
940
|
-
uploadFailed: "couldn't upload the file",
|
|
941
|
-
recordVoice: "Record voice note",
|
|
942
|
-
voiceNote: "Voice note",
|
|
943
|
-
cancelVoice: "Cancel voice note",
|
|
944
|
-
stopAndSendVoice: "Stop and send voice note",
|
|
945
|
-
micDenied: "I don't have permission to use the microphone.",
|
|
946
|
-
voiceEmpty: "nothing was understood in the voice note",
|
|
947
|
-
voiceFailed: "couldn't send the voice note",
|
|
948
|
-
model: "Model",
|
|
949
|
-
thinking: "Thinking\u2026",
|
|
950
|
-
howItGoes: (s) => s < 6 ? "Thinking\u2026" : s < 15 ? "Working\u2026" : s < 60 ? "On it\u2026" : s < 120 ? "This is taking a bit\u2026" : s < 300 ? "Been at it a while\u2026" : "This is taking long \u2014 you can stop me",
|
|
951
|
-
stillWorking: "On it\u2026",
|
|
952
|
-
retry: "Retry",
|
|
953
|
-
copy: "Copy",
|
|
954
|
-
copied: "Copied",
|
|
955
|
-
copyMessage: "Copy message",
|
|
956
|
-
worked: (s) => `Worked ${s} s`,
|
|
957
|
-
stepsExpand: "See step details",
|
|
958
|
-
stepsCollapse: "Collapse the steps",
|
|
959
|
-
earlierSteps: (n) => n === 1 ? "1 earlier step" : `${n} earlier steps`,
|
|
960
|
-
withProblems: (n) => `${n} with problems`,
|
|
961
|
-
running: "Running",
|
|
962
|
-
done: "Done",
|
|
963
|
-
failed: "Failed",
|
|
964
|
-
step: "Step",
|
|
965
|
-
replyOptions: "Reply options",
|
|
966
|
-
linkTitle: "You're about to leave",
|
|
967
|
-
linkCopy: "Copy",
|
|
968
|
-
linkCopied: "Copied",
|
|
969
|
-
linkOpen: "Open",
|
|
970
|
-
close: "Close",
|
|
971
|
-
goToLatest: "Go to latest message",
|
|
972
|
-
steps: { waking: "Waking the agent\u2026", session: "Starting the session\u2026", compacting: "Compacting the conversation\u2026" },
|
|
973
|
-
loadOlder: "Load earlier messages",
|
|
974
|
-
loadingOlder: "Loading\u2026",
|
|
975
|
-
continueRun: "Continue",
|
|
976
|
-
runCut: "The answer was cut off before it finished.",
|
|
977
|
-
stalled: "Got stuck, still trying\u2026",
|
|
978
|
-
truncated: "The answer is incomplete.",
|
|
979
|
-
attachmentFailed: (name, reason) => reason ? `Couldn't read ${name}: ${reason}` : `Couldn't read ${name}`,
|
|
980
|
-
queued: "Sends when this finishes",
|
|
981
|
-
subagentsWorking: (n) => n === 1 ? "1 agent working" : `${n} agents working`,
|
|
982
|
-
subagentsDone: (n) => n === 1 ? "1 agent finished" : `${n} agents finished`,
|
|
983
|
-
subagentStop: "Stop",
|
|
984
|
-
subagentStatus: { running: "Working", completed: "Done", failed: "Failed", stopped: "Stopped" },
|
|
985
|
-
confirmTitle: "I need your permission to",
|
|
986
|
-
approve: "Approve",
|
|
987
|
-
reject: "Reject",
|
|
988
|
-
expiresIn: (t) => `Expires in ${t}`,
|
|
989
|
-
expiredNow: "Expired without an answer",
|
|
990
|
-
decisionApproved: "You approved",
|
|
991
|
-
decisionRejected: "You rejected",
|
|
992
|
-
decisionExpired: "Expired",
|
|
993
|
-
decisionCancelled: "You dismissed",
|
|
994
|
-
stampCancelled: "Dismissed",
|
|
995
|
-
stampApproved: "Approved",
|
|
996
|
-
stampRejected: "Rejected",
|
|
997
|
-
stampExpired: "Expired"
|
|
998
|
-
};
|
|
999
|
-
|
|
1000
|
-
// src/react/context.tsx
|
|
1001
|
-
var PilotoContext = createContext2({
|
|
1002
|
-
strings: STRINGS_ES,
|
|
1003
|
-
toolVerbs: TOOL_VERBS_ES,
|
|
1004
|
-
toolIcons: {},
|
|
1005
|
-
formatUserText: cleanUserText,
|
|
1006
|
-
theme: "light",
|
|
1007
|
-
skin: "ghosty",
|
|
1008
|
-
markdown: {}
|
|
1009
|
-
});
|
|
1010
|
-
var usePiloto = () => useContext2(PilotoContext);
|
|
1011
|
-
function rootProps(theme, skin = "ghosty") {
|
|
1012
|
-
return { className: "piloto", "data-theme": theme, "data-skin": skin };
|
|
1013
|
-
}
|
|
1014
|
-
|
|
1015
|
-
// src/react/ConfirmCard.tsx
|
|
1016
117
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
1017
118
|
var isRejectOption = (o) => /^reject|deny|cancel/i.test(o.kind ?? o.optionId);
|
|
1018
119
|
var mmss = (ms) => {
|
|
@@ -1101,10 +202,10 @@ function DecisionLines({ decisions }) {
|
|
|
1101
202
|
const { strings: t } = usePiloto();
|
|
1102
203
|
if (!decisions.length) return null;
|
|
1103
204
|
return /* @__PURE__ */ jsx("ul", { className: "piloto-decisions", children: decisions.map((d) => {
|
|
1104
|
-
const
|
|
205
|
+
const Icon = d.status === "approved" ? CircleCheck : d.status === "expired" ? Clock : CircleSlash;
|
|
1105
206
|
const label = d.status === "approved" ? t.decisionApproved : d.status === "rejected" ? t.decisionRejected : d.status === "cancelled" ? t.decisionCancelled : t.decisionExpired;
|
|
1106
207
|
return /* @__PURE__ */ jsxs("li", { className: "piloto-decision", "data-status": d.status, children: [
|
|
1107
|
-
/* @__PURE__ */ jsx(
|
|
208
|
+
/* @__PURE__ */ jsx(Icon, { className: "h-4 w-4 shrink-0", "aria-hidden": true }),
|
|
1108
209
|
/* @__PURE__ */ jsxs("span", { className: "min-w-0", children: [
|
|
1109
210
|
/* @__PURE__ */ jsxs("strong", { children: [
|
|
1110
211
|
label,
|
|
@@ -1123,11 +224,11 @@ function DecisionLines({ decisions }) {
|
|
|
1123
224
|
}
|
|
1124
225
|
|
|
1125
226
|
// src/react/Markdown.tsx
|
|
1126
|
-
import { useState as useState3 } from "react";
|
|
227
|
+
import { useContext as useContext2, useState as useState3 } from "react";
|
|
1127
228
|
import { Streamdown } from "streamdown";
|
|
1128
229
|
|
|
1129
230
|
// src/react/TextAtPace.tsx
|
|
1130
|
-
import { createContext
|
|
231
|
+
import { createContext, memo, useContext, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
1131
232
|
import { Block } from "streamdown";
|
|
1132
233
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
1133
234
|
var CHUNK_MS = 400;
|
|
@@ -1195,9 +296,9 @@ function useTextAtPace(text, live, whole = false) {
|
|
|
1195
296
|
if (!animate.current) return { visible: text, animate: false };
|
|
1196
297
|
return { visible: text.slice(0, Math.min(released, text.length)), animate: true };
|
|
1197
298
|
}
|
|
1198
|
-
var ChunksContext =
|
|
299
|
+
var ChunksContext = createContext(null);
|
|
1199
300
|
function useChunkRegistry() {
|
|
1200
|
-
return
|
|
301
|
+
return useMemo(() => /* @__PURE__ */ new Map(), []);
|
|
1201
302
|
}
|
|
1202
303
|
var UNTOUCHED = /* @__PURE__ */ new Set(["pre", "code", "svg", "math", "script", "style"]);
|
|
1203
304
|
var STYLE = `gs-tramo ${CHUNK_MS}ms linear both`;
|
|
@@ -1253,9 +354,9 @@ function chunksPlugin(state) {
|
|
|
1253
354
|
};
|
|
1254
355
|
}
|
|
1255
356
|
var ChunkedBlock = memo(function ChunkedBlock2(props) {
|
|
1256
|
-
const ctx =
|
|
357
|
+
const ctx = useContext(ChunksContext);
|
|
1257
358
|
const key = `${ctx?.part ?? 0}-${props.index}`;
|
|
1258
|
-
const plugins =
|
|
359
|
+
const plugins = useMemo(() => {
|
|
1259
360
|
if (!ctx) return props.rehypePlugins;
|
|
1260
361
|
let state = ctx.registry.get(key);
|
|
1261
362
|
if (!state) {
|
|
@@ -1323,7 +424,8 @@ var linkSafety = { enabled: true, renderModal: (p) => /* @__PURE__ */ jsx3(LinkS
|
|
|
1323
424
|
function Markdown({ children, animate = false, className }) {
|
|
1324
425
|
const { markdown } = usePiloto();
|
|
1325
426
|
const registry = useChunkRegistry();
|
|
1326
|
-
const
|
|
427
|
+
const turn = useContext2(TurnContext);
|
|
428
|
+
const text = markdown.transform ? markdown.transform(children, turn) : children;
|
|
1327
429
|
const onClick = markdown.onLinkClick ? (e) => {
|
|
1328
430
|
const a = e.target.closest("a[href]");
|
|
1329
431
|
if (!a) return;
|
|
@@ -1675,17 +777,21 @@ function TurnFooter({ text, seconds, onRetry, showCopy = true, showDuration = tr
|
|
|
1675
777
|
] })
|
|
1676
778
|
] });
|
|
1677
779
|
}
|
|
1678
|
-
function AgentBubble({ turn, live, onRetry, onOption, showUsage = true, showCopy = true, showDuration = true, renderDeliveries }) {
|
|
780
|
+
function AgentBubble({ turn, live, onRetry, onOption, showUsage = true, showCopy = true, showDuration = true, renderDeliveries, renderTools, renderBefore, blocks }) {
|
|
1679
781
|
const { strings: t } = usePiloto();
|
|
1680
|
-
const
|
|
782
|
+
const extracted = blocks ? extractBlocks(turn.text ?? "", blocks.langs, turn.cuts) : { text: turn.text ?? "", cuts: turn.cuts, blocks: [] };
|
|
783
|
+
const closed = !live && !turn.tools?.some((x) => x.status === "pending");
|
|
784
|
+
const narrated = splitNarration(extracted.text, extracted.cuts, closed);
|
|
1681
785
|
const visible = narrated.rest;
|
|
1682
786
|
const options = onOption && !live && visible ? extractReplyOptions(visible) : null;
|
|
1683
|
-
return /* @__PURE__ */ jsxs4("div", { className: "gc-msg-agent min-w-0 max-w-[90%]", children: [
|
|
787
|
+
return /* @__PURE__ */ jsx6(TurnContext.Provider, { value: turn, children: /* @__PURE__ */ jsxs4("div", { className: "gc-msg-agent min-w-0 max-w-[90%]", children: [
|
|
1684
788
|
turn.thought && /* @__PURE__ */ jsxs4("details", { className: "mb-3 text-xs text-text-secondary", children: [
|
|
1685
789
|
/* @__PURE__ */ jsx6("summary", { className: "cursor-pointer select-none", children: t.thinking }),
|
|
1686
790
|
/* @__PURE__ */ jsx6("p", { className: "mt-2 whitespace-pre-wrap border-l-2 border-border-secondary pl-3", children: turn.thought })
|
|
1687
791
|
] }),
|
|
1688
792
|
turn.tools && turn.tools.length > 0 && /* @__PURE__ */ jsx6(AgentSteps, { tools: turn.tools, live }),
|
|
793
|
+
turn.tools && turn.tools.length > 0 && renderTools?.(turn, live),
|
|
794
|
+
renderBefore?.(turn, live),
|
|
1689
795
|
narrated.steps.length > 0 && /* @__PURE__ */ jsx6(Narration, { steps: narrated.steps }),
|
|
1690
796
|
options ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
1691
797
|
options.before && /* @__PURE__ */ jsx6(AnswerText, { text: options.before, live }),
|
|
@@ -1694,593 +800,21 @@ function AgentBubble({ turn, live, onRetry, onOption, showUsage = true, showCopy
|
|
|
1694
800
|
// Cada tramo nuevo tras una herramienta monta su propio ritmo (empieza de cero).
|
|
1695
801
|
visible && /* @__PURE__ */ jsx6(AnswerText, { text: visible, live }, `r${narrated.steps.length}`)
|
|
1696
802
|
),
|
|
803
|
+
extracted.blocks.length > 0 && blocks.render(extracted.blocks, turn, live),
|
|
1697
804
|
renderDeliveries?.(turn, live),
|
|
1698
805
|
turn.decisions?.length ? /* @__PURE__ */ jsx6(DecisionLines, { decisions: turn.decisions }) : null,
|
|
1699
806
|
showUsage && turn.usage && /* @__PURE__ */ jsx6(UsageStats, { ...turn.usage }),
|
|
1700
807
|
turn.text && !live && /* @__PURE__ */ jsx6(TurnFooter, { text: turn.text, seconds: turn.seconds, onRetry, showCopy, showDuration })
|
|
1701
|
-
] });
|
|
1702
|
-
}
|
|
1703
|
-
|
|
1704
|
-
// src/react/Chips.tsx
|
|
1705
|
-
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1706
|
-
function ReferenceChips({ references, onRemove, onActivate }) {
|
|
1707
|
-
const { strings: t } = usePiloto();
|
|
1708
|
-
if (!references.length) return null;
|
|
1709
|
-
const pointed = references.filter((r) => r.prompt);
|
|
1710
|
-
const plain = references.filter((r) => !r.prompt);
|
|
1711
|
-
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
1712
|
-
pointed.map((r) => /* @__PURE__ */ jsx7("div", { className: "mb-2 flex", children: /* @__PURE__ */ jsxs5("span", { className: "inline-flex max-w-full items-center gap-1.5 rounded-full border border-brand-500/40 bg-brand-500/10 py-1 pl-2.5 pr-1 text-xs text-text-primary", children: [
|
|
1713
|
-
/* @__PURE__ */ jsx7(Crosshair, { size: 13, className: "shrink-0 text-brand-500" }),
|
|
1714
|
-
/* @__PURE__ */ jsx7("span", { className: "shrink-0 font-semibold", children: r.label }),
|
|
1715
|
-
r.hint && /* @__PURE__ */ jsxs5("span", { className: "truncate text-text-secondary", children: [
|
|
1716
|
-
"\xAB",
|
|
1717
|
-
r.hint,
|
|
1718
|
-
"\xBB"
|
|
1719
|
-
] }),
|
|
1720
|
-
/* @__PURE__ */ jsx7(
|
|
1721
|
-
"button",
|
|
1722
|
-
{
|
|
1723
|
-
type: "button",
|
|
1724
|
-
onClick: () => onRemove(r.id),
|
|
1725
|
-
"aria-label": t.removeReference,
|
|
1726
|
-
className: "grid size-5 shrink-0 cursor-pointer place-items-center rounded-full text-text-tertiary hover:bg-background-secondary hover:text-text-primary",
|
|
1727
|
-
children: /* @__PURE__ */ jsx7(X, { size: 12 })
|
|
1728
|
-
}
|
|
1729
|
-
)
|
|
1730
|
-
] }) }, r.id)),
|
|
1731
|
-
plain.length > 0 && /* @__PURE__ */ jsx7("div", { className: "flex flex-wrap gap-1.5", children: plain.map((r) => /* @__PURE__ */ jsxs5("span", { className: "inline-flex items-center gap-1 rounded-full border border-border-primary bg-background-secondary py-0.5 pl-2 pr-1 text-xs text-text-primary", children: [
|
|
1732
|
-
/* @__PURE__ */ jsx7("button", { type: "button", onClick: () => onActivate?.(r), className: "underline-offset-2 hover:underline", children: r.label }),
|
|
1733
|
-
/* @__PURE__ */ jsx7(
|
|
1734
|
-
"button",
|
|
1735
|
-
{
|
|
1736
|
-
type: "button",
|
|
1737
|
-
onClick: () => onRemove(r.id),
|
|
1738
|
-
"aria-label": t.removeReference,
|
|
1739
|
-
className: "flex h-4 w-4 items-center justify-center rounded-full text-text-tertiary hover:bg-background-tertiary hover:text-text-primary",
|
|
1740
|
-
children: /* @__PURE__ */ jsx7(X, { className: "h-3 w-3" })
|
|
1741
|
-
}
|
|
1742
|
-
)
|
|
1743
|
-
] }, r.id)) })
|
|
1744
|
-
] });
|
|
1745
|
-
}
|
|
1746
|
-
function Suggestions({ items, onPick, onPrefill, disabled }) {
|
|
1747
|
-
if (!items.length) return null;
|
|
1748
|
-
return /* @__PURE__ */ jsx7("div", { className: "mt-4 flex flex-wrap justify-center gap-2", children: items.map((c) => /* @__PURE__ */ jsx7(
|
|
1749
|
-
"button",
|
|
1750
|
-
{
|
|
1751
|
-
type: "button",
|
|
1752
|
-
onClick: () => onPrefill && /:\s*$/.test(c) ? onPrefill(c) : onPick(c),
|
|
1753
|
-
disabled,
|
|
1754
|
-
className: "gc-chip rounded-full bg-irongray/10 px-3.5 py-1.5 text-xs font-medium text-metal transition-colors hover:bg-irongray/20 hover:text-dark disabled:opacity-40",
|
|
1755
|
-
children: c
|
|
1756
|
-
},
|
|
1757
|
-
c
|
|
1758
|
-
)) });
|
|
1759
|
-
}
|
|
1760
|
-
|
|
1761
|
-
// src/react/Composer.tsx
|
|
1762
|
-
import { useCallback, useEffect as useEffect3, useRef as useRef3, useState as useState6 } from "react";
|
|
1763
|
-
import { Fragment as Fragment5, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1764
|
-
var MAX_HEIGHT = 240;
|
|
1765
|
-
var BY_EXTENSION = {
|
|
1766
|
-
png: "image/png",
|
|
1767
|
-
jpg: "image/jpeg",
|
|
1768
|
-
jpeg: "image/jpeg",
|
|
1769
|
-
gif: "image/gif",
|
|
1770
|
-
webp: "image/webp",
|
|
1771
|
-
heic: "image/heic",
|
|
1772
|
-
pdf: "application/pdf",
|
|
1773
|
-
csv: "text/csv",
|
|
1774
|
-
txt: "text/plain",
|
|
1775
|
-
md: "text/markdown",
|
|
1776
|
-
json: "application/json"
|
|
1777
|
-
};
|
|
1778
|
-
function mimeOf(file) {
|
|
1779
|
-
if (file.type) return file.type;
|
|
1780
|
-
const ext = (file.name.match(/\.([A-Za-z0-9]+)$/)?.[1] || "").toLowerCase();
|
|
1781
|
-
return BY_EXTENSION[ext] ?? "application/octet-stream";
|
|
1782
|
-
}
|
|
1783
|
-
var isText = (mime) => mime.startsWith("text/") || mime === "application/json" || mime.endsWith("+json") || mime.endsWith("+xml");
|
|
1784
|
-
function shortSize(bytes) {
|
|
1785
|
-
if (bytes < 1024) return `${bytes} B`;
|
|
1786
|
-
if (bytes < 1024 * 1024) return `${Math.round(bytes / 1024)} KB`;
|
|
1787
|
-
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
1788
|
-
}
|
|
1789
|
-
function readInline(file) {
|
|
1790
|
-
return new Promise((resolve, reject) => {
|
|
1791
|
-
const fr = new FileReader();
|
|
1792
|
-
fr.onload = () => {
|
|
1793
|
-
const result = String(fr.result);
|
|
1794
|
-
const comma = result.indexOf(",");
|
|
1795
|
-
resolve({ name: file.name, mimeType: mimeOf(file), data: comma === -1 ? result : result.slice(comma + 1) });
|
|
1796
|
-
};
|
|
1797
|
-
fr.onerror = () => reject(fr.error);
|
|
1798
|
-
fr.readAsDataURL(file);
|
|
1799
|
-
});
|
|
1800
|
-
}
|
|
1801
|
-
function Composer({
|
|
1802
|
-
onSubmit,
|
|
1803
|
-
onStop,
|
|
1804
|
-
busy = false,
|
|
1805
|
-
canSteer = true,
|
|
1806
|
-
placeholder,
|
|
1807
|
-
initialValue = "",
|
|
1808
|
-
autoFocus = true,
|
|
1809
|
-
canSeeImages = true,
|
|
1810
|
-
attachments: withFiles = false,
|
|
1811
|
-
upload,
|
|
1812
|
-
transcribe,
|
|
1813
|
-
voiceNoteText,
|
|
1814
|
-
models = [],
|
|
1815
|
-
currentModel = null,
|
|
1816
|
-
onModelChange,
|
|
1817
|
-
references = [],
|
|
1818
|
-
onRemoveReference,
|
|
1819
|
-
onActivateReference,
|
|
1820
|
-
extras,
|
|
1821
|
-
maxFiles = 8,
|
|
1822
|
-
maxFileMb = 25
|
|
1823
|
-
}) {
|
|
1824
|
-
const { strings: t } = usePiloto();
|
|
1825
|
-
const [value, setValue] = useState6(initialValue);
|
|
1826
|
-
const [files, setFiles] = useState6([]);
|
|
1827
|
-
const [dragging, setDragging] = useState6(false);
|
|
1828
|
-
const [notice, setNotice] = useState6(null);
|
|
1829
|
-
const [uploading, setUploading] = useState6(false);
|
|
1830
|
-
const ref = useRef3(null);
|
|
1831
|
-
const fileRef = useRef3(null);
|
|
1832
|
-
const nextId = useRef3(0);
|
|
1833
|
-
const urls = useRef3(/* @__PURE__ */ new Set());
|
|
1834
|
-
const releaseUrl = (url) => {
|
|
1835
|
-
urls.current.delete(url);
|
|
1836
|
-
URL.revokeObjectURL(url);
|
|
1837
|
-
};
|
|
1838
|
-
useEffect3(() => {
|
|
1839
|
-
if (!autoFocus) return;
|
|
1840
|
-
const id = requestAnimationFrame(() => {
|
|
1841
|
-
const el = ref.current;
|
|
1842
|
-
if (!el) return;
|
|
1843
|
-
el.focus({ preventScroll: true });
|
|
1844
|
-
el.setSelectionRange(el.value.length, el.value.length);
|
|
1845
|
-
});
|
|
1846
|
-
return () => cancelAnimationFrame(id);
|
|
1847
|
-
}, [autoFocus]);
|
|
1848
|
-
useEffect3(
|
|
1849
|
-
() => () => {
|
|
1850
|
-
for (const url of urls.current) URL.revokeObjectURL(url);
|
|
1851
|
-
urls.current.clear();
|
|
1852
|
-
},
|
|
1853
|
-
[]
|
|
1854
|
-
);
|
|
1855
|
-
useEffect3(() => {
|
|
1856
|
-
const el = ref.current;
|
|
1857
|
-
if (!el) return;
|
|
1858
|
-
if (!value) {
|
|
1859
|
-
el.style.height = "";
|
|
1860
|
-
return;
|
|
1861
|
-
}
|
|
1862
|
-
el.style.height = "0px";
|
|
1863
|
-
el.style.height = `${Math.min(el.scrollHeight, MAX_HEIGHT)}px`;
|
|
1864
|
-
}, [value]);
|
|
1865
|
-
const addFiles = useCallback(
|
|
1866
|
-
(list) => {
|
|
1867
|
-
if (busy) return;
|
|
1868
|
-
const rejected = [];
|
|
1869
|
-
setFiles((prev) => {
|
|
1870
|
-
const next = [...prev];
|
|
1871
|
-
for (const file of Array.from(list)) {
|
|
1872
|
-
const mime = mimeOf(file);
|
|
1873
|
-
if (file.size > maxFileMb * 1024 * 1024) {
|
|
1874
|
-
rejected.push(t.tooBig(file.name, maxFileMb));
|
|
1875
|
-
continue;
|
|
1876
|
-
}
|
|
1877
|
-
if (next.length >= maxFiles) {
|
|
1878
|
-
rejected.push(t.tooMany(maxFiles));
|
|
1879
|
-
break;
|
|
1880
|
-
}
|
|
1881
|
-
if (mime.startsWith("image/") && !canSeeImages) {
|
|
1882
|
-
rejected.push(t.cantSeeImage(file.name));
|
|
1883
|
-
continue;
|
|
1884
|
-
}
|
|
1885
|
-
if (!mime.startsWith("image/") && !isText(mime) && !upload) {
|
|
1886
|
-
rejected.push(t.cantUpload(file.name));
|
|
1887
|
-
continue;
|
|
1888
|
-
}
|
|
1889
|
-
const url = URL.createObjectURL(file);
|
|
1890
|
-
urls.current.add(url);
|
|
1891
|
-
next.push({ id: ++nextId.current, file, url });
|
|
1892
|
-
}
|
|
1893
|
-
return next;
|
|
1894
|
-
});
|
|
1895
|
-
setNotice(rejected.length ? rejected.join(" \xB7 ") : null);
|
|
1896
|
-
ref.current?.focus({ preventScroll: true });
|
|
1897
|
-
},
|
|
1898
|
-
[busy, canSeeImages, upload, maxFiles, maxFileMb, t]
|
|
1899
|
-
);
|
|
1900
|
-
useEffect3(() => {
|
|
1901
|
-
if (!withFiles) return;
|
|
1902
|
-
let inside = 0;
|
|
1903
|
-
const hasFiles = (e) => Array.from(e.dataTransfer?.types ?? []).includes("Files");
|
|
1904
|
-
const enter = (e) => {
|
|
1905
|
-
if (!hasFiles(e)) return;
|
|
1906
|
-
e.preventDefault();
|
|
1907
|
-
inside++;
|
|
1908
|
-
if (!busy) setDragging(true);
|
|
1909
|
-
};
|
|
1910
|
-
const over = (e) => {
|
|
1911
|
-
if (hasFiles(e)) e.preventDefault();
|
|
1912
|
-
};
|
|
1913
|
-
const leave = (e) => {
|
|
1914
|
-
if (!hasFiles(e)) return;
|
|
1915
|
-
inside = Math.max(0, inside - 1);
|
|
1916
|
-
if (inside === 0) setDragging(false);
|
|
1917
|
-
};
|
|
1918
|
-
const drop = (e) => {
|
|
1919
|
-
if (!hasFiles(e)) return;
|
|
1920
|
-
e.preventDefault();
|
|
1921
|
-
inside = 0;
|
|
1922
|
-
setDragging(false);
|
|
1923
|
-
if (e.dataTransfer?.files.length) addFiles(e.dataTransfer.files);
|
|
1924
|
-
};
|
|
1925
|
-
window.addEventListener("dragenter", enter);
|
|
1926
|
-
window.addEventListener("dragover", over);
|
|
1927
|
-
window.addEventListener("dragleave", leave);
|
|
1928
|
-
window.addEventListener("drop", drop);
|
|
1929
|
-
return () => {
|
|
1930
|
-
window.removeEventListener("dragenter", enter);
|
|
1931
|
-
window.removeEventListener("dragover", over);
|
|
1932
|
-
window.removeEventListener("dragleave", leave);
|
|
1933
|
-
window.removeEventListener("drop", drop);
|
|
1934
|
-
};
|
|
1935
|
-
}, [withFiles, busy, addFiles]);
|
|
1936
|
-
const removeFile = (id) => setFiles((prev) => {
|
|
1937
|
-
const out = prev.find((a) => a.id === id);
|
|
1938
|
-
if (out) releaseUrl(out.url);
|
|
1939
|
-
return prev.filter((a) => a.id !== id);
|
|
1940
|
-
});
|
|
1941
|
-
const submit = async () => {
|
|
1942
|
-
const body = value.trim();
|
|
1943
|
-
if (!body && files.length === 0 && references.length === 0) return;
|
|
1944
|
-
if (busy && (files.length > 0 || !canSteer)) return;
|
|
1945
|
-
if (uploading) return;
|
|
1946
|
-
let atts = [];
|
|
1947
|
-
if (files.length) setUploading(true);
|
|
1948
|
-
try {
|
|
1949
|
-
atts = await Promise.all(
|
|
1950
|
-
files.map(async (a) => {
|
|
1951
|
-
const mime = mimeOf(a.file);
|
|
1952
|
-
if (mime.startsWith("image/") || isText(mime)) return readInline(a.file);
|
|
1953
|
-
const up = await upload(a.file);
|
|
1954
|
-
return { name: a.file.name, mimeType: mime, url: up.url };
|
|
1955
|
-
})
|
|
1956
|
-
);
|
|
1957
|
-
} catch (e) {
|
|
1958
|
-
setNotice(e instanceof Error ? e.message : t.uploadFailed);
|
|
1959
|
-
return;
|
|
1960
|
-
} finally {
|
|
1961
|
-
setUploading(false);
|
|
1962
|
-
}
|
|
1963
|
-
onSubmit(body, atts);
|
|
1964
|
-
setValue("");
|
|
1965
|
-
setNotice(null);
|
|
1966
|
-
for (const a of files) releaseUrl(a.url);
|
|
1967
|
-
setFiles([]);
|
|
1968
|
-
};
|
|
1969
|
-
const [recording, setRecording] = useState6(false);
|
|
1970
|
-
const [transcribing, setTranscribing] = useState6(false);
|
|
1971
|
-
const [wave, setWave] = useState6([]);
|
|
1972
|
-
const [seconds, setSeconds] = useState6(0);
|
|
1973
|
-
const recRef = useRef3(null);
|
|
1974
|
-
const pieces = useRef3([]);
|
|
1975
|
-
const cancelRef = useRef3(false);
|
|
1976
|
-
const meter = useRef3(null);
|
|
1977
|
-
const [hasMic, setHasMic] = useState6(false);
|
|
1978
|
-
useEffect3(() => setHasMic(typeof window !== "undefined" && "MediaRecorder" in window && Boolean(navigator.mediaDevices?.getUserMedia)), []);
|
|
1979
|
-
const canRecord = Boolean(transcribe) && hasMic;
|
|
1980
|
-
const toggleRecording = async () => {
|
|
1981
|
-
if (recording) {
|
|
1982
|
-
cancelRef.current = false;
|
|
1983
|
-
recRef.current?.stop();
|
|
1984
|
-
return;
|
|
1985
|
-
}
|
|
1986
|
-
try {
|
|
1987
|
-
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
|
|
1988
|
-
const mime = ["audio/webm;codecs=opus", "audio/webm", "audio/mp4"].find((m) => MediaRecorder.isTypeSupported(m)) ?? "";
|
|
1989
|
-
const rec = new MediaRecorder(stream, mime ? { mimeType: mime } : void 0);
|
|
1990
|
-
pieces.current = [];
|
|
1991
|
-
rec.ondataavailable = (e) => {
|
|
1992
|
-
if (e.data.size > 0) pieces.current.push(e.data);
|
|
1993
|
-
};
|
|
1994
|
-
const ctx = new AudioContext();
|
|
1995
|
-
const an = ctx.createAnalyser();
|
|
1996
|
-
an.fftSize = 512;
|
|
1997
|
-
ctx.createMediaStreamSource(stream).connect(an);
|
|
1998
|
-
const buf = new Uint8Array(an.fftSize);
|
|
1999
|
-
let lastTick = 0;
|
|
2000
|
-
const tick = (time) => {
|
|
2001
|
-
if (time - lastTick > 80) {
|
|
2002
|
-
lastTick = time;
|
|
2003
|
-
an.getByteTimeDomainData(buf);
|
|
2004
|
-
let acc = 0;
|
|
2005
|
-
for (let i = 0; i < buf.length; i++) {
|
|
2006
|
-
const v = (buf[i] - 128) / 128;
|
|
2007
|
-
acc += v * v;
|
|
2008
|
-
}
|
|
2009
|
-
setWave((w) => [...w.slice(-59), Math.min(1, Math.sqrt(acc / buf.length) * 4)]);
|
|
2010
|
-
}
|
|
2011
|
-
if (meter.current) meter.current.raf = requestAnimationFrame(tick);
|
|
2012
|
-
};
|
|
2013
|
-
const start = Date.now();
|
|
2014
|
-
meter.current = { ctx, raf: requestAnimationFrame(tick), timer: window.setInterval(() => setSeconds(Math.floor((Date.now() - start) / 1e3)), 250) };
|
|
2015
|
-
rec.onstop = async () => {
|
|
2016
|
-
stream.getTracks().forEach((tr) => tr.stop());
|
|
2017
|
-
if (meter.current) {
|
|
2018
|
-
cancelAnimationFrame(meter.current.raf);
|
|
2019
|
-
clearInterval(meter.current.timer);
|
|
2020
|
-
void meter.current.ctx.close();
|
|
2021
|
-
meter.current = null;
|
|
2022
|
-
}
|
|
2023
|
-
setRecording(false);
|
|
2024
|
-
setWave([]);
|
|
2025
|
-
setSeconds(0);
|
|
2026
|
-
if (cancelRef.current) return;
|
|
2027
|
-
const type = rec.mimeType || mime || "audio/webm";
|
|
2028
|
-
const blob = new Blob(pieces.current, { type });
|
|
2029
|
-
if (blob.size < 1e3) return;
|
|
2030
|
-
setTranscribing(true);
|
|
2031
|
-
try {
|
|
2032
|
-
const ext = type.includes("mp4") ? "m4a" : "webm";
|
|
2033
|
-
const name = `nota-de-voz-${(/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-")}.${ext}`;
|
|
2034
|
-
const [said, up] = await Promise.all([transcribe(blob), upload ? upload(new File([blob], name, { type })) : Promise.resolve(null)]);
|
|
2035
|
-
const text = said.trim();
|
|
2036
|
-
if (!text) throw new Error(t.voiceEmpty);
|
|
2037
|
-
const atts = up ? [{ name, mimeType: type, url: up.url }] : [];
|
|
2038
|
-
onSubmit(voiceNoteText ? voiceNoteText(text) : text, atts);
|
|
2039
|
-
setNotice(null);
|
|
2040
|
-
} catch (e) {
|
|
2041
|
-
setNotice(e instanceof Error ? e.message : t.voiceFailed);
|
|
2042
|
-
} finally {
|
|
2043
|
-
setTranscribing(false);
|
|
2044
|
-
}
|
|
2045
|
-
};
|
|
2046
|
-
recRef.current = rec;
|
|
2047
|
-
rec.start();
|
|
2048
|
-
setRecording(true);
|
|
2049
|
-
} catch {
|
|
2050
|
-
setNotice(t.micDenied);
|
|
2051
|
-
}
|
|
2052
|
-
};
|
|
2053
|
-
const canSend = Boolean(value.trim() || files.length > 0 || references.length > 0);
|
|
2054
|
-
return /* @__PURE__ */ jsx8("div", { className: "gc-input rounded-(--piloto-radius-input) border-(length:--piloto-border-width) border-outlines bg-(--piloto-composer-bg) shadow-(--piloto-shadow-input) transition-colors focus-within:border-brand-300", children: /* @__PURE__ */ jsxs6("div", { className: `flex flex-col gap-2 p-3 transition-shadow ${withFiles && dragging ? "rounded-2xl bg-background-secondary/40 ring-2 ring-inset ring-ring-info" : ""}`, children: [
|
|
2055
|
-
withFiles && dragging && /* @__PURE__ */ jsx8("div", { className: "pointer-events-none fixed inset-0 z-50 flex items-center justify-center bg-background-primary/80 p-6 backdrop-blur-sm", children: /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center gap-2 rounded-3xl border-2 border-dashed border-brand-500 bg-background-primary px-10 py-8 text-center shadow-lg", children: [
|
|
2056
|
-
/* @__PURE__ */ jsx8(Paperclip, { className: "size-7 text-brand-500" }),
|
|
2057
|
-
/* @__PURE__ */ jsx8("p", { className: "text-base font-semibold text-text-primary", children: t.dropFiles }),
|
|
2058
|
-
/* @__PURE__ */ jsx8("p", { className: "text-xs text-text-secondary", children: t.dropHint })
|
|
2059
|
-
] }) }),
|
|
2060
|
-
/* @__PURE__ */ jsx8(
|
|
2061
|
-
"input",
|
|
2062
|
-
{
|
|
2063
|
-
ref: fileRef,
|
|
2064
|
-
type: "file",
|
|
2065
|
-
multiple: true,
|
|
2066
|
-
hidden: true,
|
|
2067
|
-
onChange: (e) => {
|
|
2068
|
-
if (e.target.files) addFiles(e.target.files);
|
|
2069
|
-
e.target.value = "";
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
),
|
|
2073
|
-
notice && /* @__PURE__ */ jsx8("p", { className: "text-xs text-text-danger", children: notice }),
|
|
2074
|
-
uploading && /* @__PURE__ */ jsxs6("p", { className: "flex items-center gap-1.5 text-xs text-text-secondary", children: [
|
|
2075
|
-
/* @__PURE__ */ jsx8(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin" }),
|
|
2076
|
-
files.length > 1 ? t.uploadingN(files.length) : t.uploading
|
|
2077
|
-
] }),
|
|
2078
|
-
withFiles && files.length > 0 && /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-2", children: files.map((a) => /* @__PURE__ */ jsxs6("div", { className: "relative h-16 w-16 overflow-hidden rounded-lg border border-border-primary bg-background-secondary", children: [
|
|
2079
|
-
mimeOf(a.file).startsWith("image/") ? /* @__PURE__ */ jsx8("img", { src: a.url, alt: a.file.name, className: "h-full w-full object-cover" }) : (
|
|
2080
|
-
// Un PDF pintado con <img> es un recuadro roto: nombre, extensión y peso.
|
|
2081
|
-
/* @__PURE__ */ jsxs6("span", { className: "flex h-full w-full flex-col items-center justify-center gap-1 px-1 text-center", title: a.file.name, children: [
|
|
2082
|
-
/* @__PURE__ */ jsx8(FileText, { className: "h-4 w-4 shrink-0 text-text-tertiary" }),
|
|
2083
|
-
/* @__PURE__ */ jsx8("span", { className: "w-full truncate text-[9px] font-medium uppercase leading-none text-text-secondary", children: a.file.name.match(/\.([A-Za-z0-9]+)$/)?.[1] ?? "file" }),
|
|
2084
|
-
/* @__PURE__ */ jsx8("span", { className: "w-full truncate text-[9px] leading-none text-text-tertiary", children: shortSize(a.file.size) })
|
|
2085
|
-
] })
|
|
2086
|
-
),
|
|
2087
|
-
/* @__PURE__ */ jsx8(
|
|
2088
|
-
"button",
|
|
2089
|
-
{
|
|
2090
|
-
type: "button",
|
|
2091
|
-
onClick: () => removeFile(a.id),
|
|
2092
|
-
"aria-label": t.removeAttachment,
|
|
2093
|
-
className: "absolute top-0.5 right-0.5 flex h-5 w-5 items-center justify-center rounded-full bg-background-inverse/80 text-text-inverse shadow-sm transition-colors hover:bg-background-inverse",
|
|
2094
|
-
children: /* @__PURE__ */ jsx8(X, { className: "h-3 w-3" })
|
|
2095
|
-
}
|
|
2096
|
-
)
|
|
2097
|
-
] }, a.id)) }),
|
|
2098
|
-
/* @__PURE__ */ jsx8(ReferenceChips, { references, onRemove: (id) => onRemoveReference?.(id), onActivate: onActivateReference }),
|
|
2099
|
-
recording ? (
|
|
2100
|
-
// Grabando: la barra sustituye al campo de texto — punto rojo, reloj, la onda y las dos salidas.
|
|
2101
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex min-h-[24px] items-center gap-3 px-1", children: [
|
|
2102
|
-
/* @__PURE__ */ jsx8(
|
|
2103
|
-
"button",
|
|
2104
|
-
{
|
|
2105
|
-
type: "button",
|
|
2106
|
-
onClick: () => {
|
|
2107
|
-
cancelRef.current = true;
|
|
2108
|
-
recRef.current?.stop();
|
|
2109
|
-
},
|
|
2110
|
-
"aria-label": t.cancelVoice,
|
|
2111
|
-
title: t.cancelVoice,
|
|
2112
|
-
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-text-secondary hover:bg-background-secondary hover:text-text-primary",
|
|
2113
|
-
children: /* @__PURE__ */ jsx8(X, { className: "h-4 w-4" })
|
|
2114
|
-
}
|
|
2115
|
-
),
|
|
2116
|
-
/* @__PURE__ */ jsx8("span", { className: "h-2 w-2 shrink-0 animate-pulse rounded-full bg-red-500" }),
|
|
2117
|
-
/* @__PURE__ */ jsxs6("span", { className: "w-10 shrink-0 font-mono text-xs tabular-nums text-text-secondary", children: [
|
|
2118
|
-
Math.floor(seconds / 60),
|
|
2119
|
-
":",
|
|
2120
|
-
String(seconds % 60).padStart(2, "0")
|
|
2121
|
-
] }),
|
|
2122
|
-
/* @__PURE__ */ jsx8("div", { className: "flex h-6 min-w-0 flex-1 items-center gap-[2px] overflow-hidden", children: Array.from({ length: 60 }, (_, i) => wave[wave.length - 60 + i] ?? 0).map((v, i) => /* @__PURE__ */ jsx8("span", { className: "w-[3px] shrink-0 rounded-full bg-text-secondary/70", style: { height: `${Math.max(3, Math.round(v * 22))}px` } }, i)) }),
|
|
2123
|
-
/* @__PURE__ */ jsx8(
|
|
2124
|
-
"button",
|
|
2125
|
-
{
|
|
2126
|
-
type: "button",
|
|
2127
|
-
onClick: toggleRecording,
|
|
2128
|
-
"aria-label": t.stopAndSendVoice,
|
|
2129
|
-
title: t.send,
|
|
2130
|
-
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-brand-500 text-white hover:bg-brand-600",
|
|
2131
|
-
children: /* @__PURE__ */ jsx8(ArrowUp, { className: "h-4 w-4" })
|
|
2132
|
-
}
|
|
2133
|
-
)
|
|
2134
|
-
] })
|
|
2135
|
-
) : /* @__PURE__ */ jsx8(
|
|
2136
|
-
"textarea",
|
|
2137
|
-
{
|
|
2138
|
-
ref,
|
|
2139
|
-
rows: 1,
|
|
2140
|
-
value,
|
|
2141
|
-
placeholder,
|
|
2142
|
-
onChange: (e) => setValue(e.target.value),
|
|
2143
|
-
onKeyDown: (e) => {
|
|
2144
|
-
if (e.key === "Enter" && !e.shiftKey && !e.nativeEvent.isComposing) {
|
|
2145
|
-
e.preventDefault();
|
|
2146
|
-
void submit();
|
|
2147
|
-
} else if (e.key === "Backspace" && !value && references.length) {
|
|
2148
|
-
e.preventDefault();
|
|
2149
|
-
onRemoveReference?.(references[references.length - 1].id);
|
|
2150
|
-
}
|
|
2151
|
-
},
|
|
2152
|
-
className: "max-h-60 min-h-[24px] w-full flex-none resize-none overflow-y-auto bg-transparent px-1 text-sm leading-6 text-text-primary outline-none placeholder:text-text-tertiary"
|
|
2153
|
-
}
|
|
2154
|
-
),
|
|
2155
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between gap-2", children: [
|
|
2156
|
-
/* @__PURE__ */ jsxs6("div", { className: "@container flex min-w-0 flex-1 items-center gap-1.5 overflow-hidden", children: [
|
|
2157
|
-
withFiles && /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
2158
|
-
/* @__PURE__ */ jsx8(
|
|
2159
|
-
"button",
|
|
2160
|
-
{
|
|
2161
|
-
type: "button",
|
|
2162
|
-
onClick: () => {
|
|
2163
|
-
if (!fileRef.current) return;
|
|
2164
|
-
fileRef.current.accept = "image/*";
|
|
2165
|
-
fileRef.current.click();
|
|
2166
|
-
},
|
|
2167
|
-
disabled: busy || !canSeeImages || files.length >= maxFiles,
|
|
2168
|
-
"aria-label": canSeeImages ? t.attachImage : t.noImages,
|
|
2169
|
-
title: canSeeImages ? t.attachImage : t.noImages,
|
|
2170
|
-
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-background-secondary hover:text-text-primary disabled:opacity-30",
|
|
2171
|
-
children: /* @__PURE__ */ jsx8(Image, { className: "h-4 w-4" })
|
|
2172
|
-
}
|
|
2173
|
-
),
|
|
2174
|
-
extras,
|
|
2175
|
-
/* @__PURE__ */ jsx8(
|
|
2176
|
-
"button",
|
|
2177
|
-
{
|
|
2178
|
-
type: "button",
|
|
2179
|
-
onClick: () => {
|
|
2180
|
-
if (!fileRef.current) return;
|
|
2181
|
-
fileRef.current.accept = "";
|
|
2182
|
-
fileRef.current.click();
|
|
2183
|
-
},
|
|
2184
|
-
disabled: busy || files.length >= maxFiles,
|
|
2185
|
-
"aria-label": t.attachFile,
|
|
2186
|
-
title: t.attachFile,
|
|
2187
|
-
className: "flex h-7 w-7 shrink-0 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-background-secondary hover:text-text-primary disabled:opacity-40",
|
|
2188
|
-
children: /* @__PURE__ */ jsx8(Paperclip, { className: "h-4 w-4" })
|
|
2189
|
-
}
|
|
2190
|
-
)
|
|
2191
|
-
] }),
|
|
2192
|
-
!withFiles && extras,
|
|
2193
|
-
models.length > 0 && onModelChange && /* @__PURE__ */ jsx8(ModelPicker, { models, current: currentModel, onChange: onModelChange })
|
|
2194
|
-
] }),
|
|
2195
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 items-center gap-1.5", children: [
|
|
2196
|
-
canRecord && !recording && /* @__PURE__ */ jsx8(
|
|
2197
|
-
"button",
|
|
2198
|
-
{
|
|
2199
|
-
type: "button",
|
|
2200
|
-
onClick: toggleRecording,
|
|
2201
|
-
disabled: busy || transcribing,
|
|
2202
|
-
"aria-label": t.recordVoice,
|
|
2203
|
-
title: t.voiceNote,
|
|
2204
|
-
className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-text-secondary transition-colors hover:bg-background-secondary hover:text-text-primary disabled:opacity-40",
|
|
2205
|
-
children: transcribing ? /* @__PURE__ */ jsx8("span", { className: "h-3.5 w-3.5 animate-spin rounded-full border-2 border-current border-t-transparent" }) : /* @__PURE__ */ jsx8(Mic, { className: "h-4 w-4" })
|
|
2206
|
-
}
|
|
2207
|
-
),
|
|
2208
|
-
/* @__PURE__ */ jsx8(
|
|
2209
|
-
"button",
|
|
2210
|
-
{
|
|
2211
|
-
type: "button",
|
|
2212
|
-
onClick: busy ? onStop : () => void submit(),
|
|
2213
|
-
disabled: !busy && !canSend || uploading,
|
|
2214
|
-
"aria-label": busy ? t.stop : uploading ? t.uploading : t.send,
|
|
2215
|
-
className: `gc-send flex h-8 w-8 items-center justify-center rounded-full transition-colors ${busy || canSend || uploading ? "bg-brand-500 text-white hover:bg-brand-600" : "bg-background-disabled text-text-disabled"}`,
|
|
2216
|
-
children: busy ? /* @__PURE__ */ jsx8(Square, { className: "h-3 w-3 fill-current" }) : uploading ? /* @__PURE__ */ jsx8(LoaderCircle, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsx8(ArrowUp, { className: "h-4 w-4" })
|
|
2217
|
-
}
|
|
2218
|
-
)
|
|
2219
|
-
] })
|
|
2220
|
-
] })
|
|
2221
808
|
] }) });
|
|
2222
809
|
}
|
|
2223
|
-
function ModelPicker({ models, current, onChange }) {
|
|
2224
|
-
const { strings: t } = usePiloto();
|
|
2225
|
-
const [open, setOpen] = useState6(false);
|
|
2226
|
-
const box = useRef3(null);
|
|
2227
|
-
useEffect3(() => {
|
|
2228
|
-
if (!open) return;
|
|
2229
|
-
const outside = (e) => {
|
|
2230
|
-
if (!box.current?.contains(e.target)) setOpen(false);
|
|
2231
|
-
};
|
|
2232
|
-
const escape = (e) => e.key === "Escape" && setOpen(false);
|
|
2233
|
-
document.addEventListener("mousedown", outside);
|
|
2234
|
-
document.addEventListener("keydown", escape);
|
|
2235
|
-
return () => {
|
|
2236
|
-
document.removeEventListener("mousedown", outside);
|
|
2237
|
-
document.removeEventListener("keydown", escape);
|
|
2238
|
-
};
|
|
2239
|
-
}, [open]);
|
|
2240
|
-
if (models.length === 0) return null;
|
|
2241
|
-
const active = models.find((m) => m.value === current) ?? null;
|
|
2242
|
-
return /* @__PURE__ */ jsxs6("div", { ref: box, className: "relative", children: [
|
|
2243
|
-
/* @__PURE__ */ jsxs6(
|
|
2244
|
-
"button",
|
|
2245
|
-
{
|
|
2246
|
-
type: "button",
|
|
2247
|
-
"aria-expanded": open,
|
|
2248
|
-
onClick: () => setOpen((v) => !v),
|
|
2249
|
-
className: "flex max-w-56 items-center gap-1.5 rounded-full border border-border-primary px-2.5 py-1 text-xs text-text-secondary transition-colors outline-none hover:bg-background-secondary hover:text-text-primary",
|
|
2250
|
-
children: [
|
|
2251
|
-
/* @__PURE__ */ jsx8(Cpu, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
2252
|
-
/* @__PURE__ */ jsx8("span", { className: "truncate", children: active?.name ?? t.model }),
|
|
2253
|
-
/* @__PURE__ */ jsx8(ChevronDown, { className: "h-3.5 w-3.5 shrink-0 opacity-70" })
|
|
2254
|
-
]
|
|
2255
|
-
}
|
|
2256
|
-
),
|
|
2257
|
-
open && // Hacia ARRIBA: el selector vive pegado al borde inferior del input.
|
|
2258
|
-
/* @__PURE__ */ jsx8("div", { className: "absolute bottom-full left-0 z-20 mb-1 max-h-80 min-w-52 overflow-y-auto rounded-xl border border-border-primary bg-background-primary py-1 shadow-lg", children: models.map((m) => /* @__PURE__ */ jsxs6(
|
|
2259
|
-
"button",
|
|
2260
|
-
{
|
|
2261
|
-
type: "button",
|
|
2262
|
-
onClick: () => {
|
|
2263
|
-
onChange(m.value);
|
|
2264
|
-
setOpen(false);
|
|
2265
|
-
},
|
|
2266
|
-
className: "flex w-full items-center justify-between gap-3 px-3 py-1.5 text-left text-xs text-text-secondary transition-colors hover:bg-background-secondary hover:text-text-primary",
|
|
2267
|
-
children: [
|
|
2268
|
-
/* @__PURE__ */ jsx8("span", { className: "truncate", children: m.name }),
|
|
2269
|
-
m.value === current && /* @__PURE__ */ jsx8(Check, { className: "h-3.5 w-3.5 shrink-0 text-text-success" })
|
|
2270
|
-
]
|
|
2271
|
-
},
|
|
2272
|
-
m.value
|
|
2273
|
-
)) })
|
|
2274
|
-
] });
|
|
2275
|
-
}
|
|
2276
810
|
|
|
2277
811
|
// src/react/Status.tsx
|
|
2278
812
|
import { AnimatePresence as AnimatePresence2, motion as motion2 } from "motion/react";
|
|
2279
|
-
import { useEffect as
|
|
2280
|
-
import { jsx as
|
|
813
|
+
import { useEffect as useEffect3, useState as useState6 } from "react";
|
|
814
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2281
815
|
var STILL_WORKING_S = 90;
|
|
2282
816
|
function TypingDots() {
|
|
2283
|
-
return /* @__PURE__ */
|
|
817
|
+
return /* @__PURE__ */ jsx7("div", { className: "gc-typing flex gap-1", children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx7("span", { className: "gc-typing-dot h-2 w-2 animate-bounce rounded-full", style: { "--i": i } }, i)) });
|
|
2284
818
|
}
|
|
2285
819
|
function WaitLabel({
|
|
2286
820
|
since,
|
|
@@ -2288,9 +822,9 @@ function WaitLabel({
|
|
|
2288
822
|
step
|
|
2289
823
|
}) {
|
|
2290
824
|
const { strings: t } = usePiloto();
|
|
2291
|
-
const [mounted] =
|
|
2292
|
-
const [now, setNow] =
|
|
2293
|
-
|
|
825
|
+
const [mounted] = useState6(() => Date.now());
|
|
826
|
+
const [now, setNow] = useState6(() => Date.now());
|
|
827
|
+
useEffect3(() => {
|
|
2294
828
|
const id = setInterval(() => setNow(Date.now()), 1e3);
|
|
2295
829
|
return () => clearInterval(id);
|
|
2296
830
|
}, []);
|
|
@@ -2298,8 +832,8 @@ function WaitLabel({
|
|
|
2298
832
|
const phrases = t.thinkingPhrases;
|
|
2299
833
|
const stepText = step ? t.steps?.[step] : void 0;
|
|
2300
834
|
const what = stepText ? stepText : phrases?.length ? seconds >= STILL_WORKING_S ? t.stillWorking : phrases[Math.floor(seconds / 4) % phrases.length] : t.howItGoes(seconds);
|
|
2301
|
-
return /* @__PURE__ */
|
|
2302
|
-
/* @__PURE__ */
|
|
835
|
+
return /* @__PURE__ */ jsx7("div", { className: "flex flex-col gap-0.5 text-sm text-text-secondary", children: /* @__PURE__ */ jsxs5("p", { className: "flex items-center", children: [
|
|
836
|
+
/* @__PURE__ */ jsx7(AnimatePresence2, { mode: "wait", initial: false, children: /* @__PURE__ */ jsx7(
|
|
2303
837
|
motion2.span,
|
|
2304
838
|
{
|
|
2305
839
|
className: "gc-wait-text",
|
|
@@ -2311,7 +845,7 @@ function WaitLabel({
|
|
|
2311
845
|
},
|
|
2312
846
|
what
|
|
2313
847
|
) }),
|
|
2314
|
-
showDuration && /* @__PURE__ */
|
|
848
|
+
showDuration && /* @__PURE__ */ jsxs5("span", { className: "tabular-nums text-text-tertiary", children: [
|
|
2315
849
|
"\xA0\xB7 ",
|
|
2316
850
|
formatDuration(seconds)
|
|
2317
851
|
] })
|
|
@@ -2319,7 +853,7 @@ function WaitLabel({
|
|
|
2319
853
|
}
|
|
2320
854
|
|
|
2321
855
|
// src/react/usePilot.ts
|
|
2322
|
-
import { useCallback
|
|
856
|
+
import { useCallback, useEffect as useEffect4, useMemo as useMemo2, useRef as useRef3, useState as useState7 } from "react";
|
|
2323
857
|
var MAX_QUEUE_TRIES = 3;
|
|
2324
858
|
var uuid = () => {
|
|
2325
859
|
const c = globalThis.crypto;
|
|
@@ -2353,19 +887,29 @@ function fromUserMessage(content) {
|
|
|
2353
887
|
return { text, attachments };
|
|
2354
888
|
}
|
|
2355
889
|
function usePilot(transport, opts = {}) {
|
|
2356
|
-
const [state, setState] =
|
|
2357
|
-
const ref =
|
|
2358
|
-
const optsRef =
|
|
890
|
+
const [state, setState] = useState7(() => createPilotState(opts.initialTurns ?? []));
|
|
891
|
+
const ref = useRef3(state);
|
|
892
|
+
const optsRef = useRef3(opts);
|
|
2359
893
|
optsRef.current = opts;
|
|
2360
|
-
const transportRef =
|
|
894
|
+
const transportRef = useRef3(transport);
|
|
2361
895
|
transportRef.current = transport;
|
|
2362
|
-
const [threadId] =
|
|
2363
|
-
const ctrl =
|
|
2364
|
-
const liveRun =
|
|
2365
|
-
const answers =
|
|
2366
|
-
const queuedTries =
|
|
2367
|
-
const flushRef =
|
|
896
|
+
const [threadId] = useState7(() => opts.threadId ?? uuid());
|
|
897
|
+
const ctrl = useRef3(null);
|
|
898
|
+
const liveRun = useRef3(null);
|
|
899
|
+
const answers = useRef3(/* @__PURE__ */ new Map());
|
|
900
|
+
const queuedTries = useRef3(/* @__PURE__ */ new Map());
|
|
901
|
+
const flushRef = useRef3(() => {
|
|
2368
902
|
});
|
|
903
|
+
const turnListeners = useRef3(/* @__PURE__ */ new Set());
|
|
904
|
+
const onTurn = useCallback((fn) => {
|
|
905
|
+
turnListeners.current.add(fn);
|
|
906
|
+
return () => void turnListeners.current.delete(fn);
|
|
907
|
+
}, []);
|
|
908
|
+
const listeners = useRef3(/* @__PURE__ */ new Set());
|
|
909
|
+
const subscribe = useCallback((fn) => {
|
|
910
|
+
listeners.current.add(fn);
|
|
911
|
+
return () => void listeners.current.delete(fn);
|
|
912
|
+
}, []);
|
|
2369
913
|
const baseInput = () => {
|
|
2370
914
|
const ctx = optsRef.current.context;
|
|
2371
915
|
return { threadId, runId: uuid(), messages: [], tools: [], context: toAgUiContext(typeof ctx === "function" ? ctx() : ctx), state: {}, forwardedProps: extraProps() };
|
|
@@ -2374,19 +918,24 @@ function usePilot(transport, opts = {}) {
|
|
|
2374
918
|
const f = optsRef.current.forwardedProps;
|
|
2375
919
|
return (typeof f === "function" ? f() : f) ?? {};
|
|
2376
920
|
};
|
|
2377
|
-
const commit =
|
|
921
|
+
const commit = useCallback((next) => {
|
|
2378
922
|
if (next === ref.current) return;
|
|
2379
923
|
ref.current = next;
|
|
2380
924
|
setState(next);
|
|
2381
925
|
const o = optsRef.current;
|
|
2382
926
|
for (const e of next.effects) {
|
|
2383
|
-
if (e.type === "turn-start")
|
|
2384
|
-
|
|
2385
|
-
|
|
927
|
+
if (e.type === "turn-start") {
|
|
928
|
+
o.onTurnStart?.();
|
|
929
|
+
for (const fn of turnListeners.current) fn({ type: "start" });
|
|
930
|
+
} else if (e.type === "turn-done") {
|
|
931
|
+
const info = { text: e.text, runId: e.runId, seconds: e.seconds, error: e.error, interrupted: e.interrupted };
|
|
932
|
+
o.onTurnDone?.(info);
|
|
933
|
+
for (const fn of turnListeners.current) fn({ type: "done", info });
|
|
934
|
+
} else if (e.type === "title") o.onTitle?.(e.title);
|
|
2386
935
|
else if (e.type === "state") o.onState?.(e.state);
|
|
2387
936
|
}
|
|
2388
937
|
}, []);
|
|
2389
|
-
const runNow =
|
|
938
|
+
const runNow = useCallback(
|
|
2390
939
|
async (partial, reopening = false) => {
|
|
2391
940
|
const t = transportRef.current;
|
|
2392
941
|
if (!t) return;
|
|
@@ -2405,6 +954,7 @@ function usePilot(transport, opts = {}) {
|
|
|
2405
954
|
(e) => {
|
|
2406
955
|
if (c.signal.aborted) return;
|
|
2407
956
|
optsRef.current.onEvent?.(e);
|
|
957
|
+
for (const fn of listeners.current) fn(e);
|
|
2408
958
|
if (e.type === "RUN_FINISHED" || e.type === "RUN_ERROR") {
|
|
2409
959
|
ended = true;
|
|
2410
960
|
liveRun.current = null;
|
|
@@ -2465,17 +1015,31 @@ function usePilot(transport, opts = {}) {
|
|
|
2465
1015
|
},
|
|
2466
1016
|
[commit, threadId]
|
|
2467
1017
|
);
|
|
2468
|
-
|
|
2469
|
-
|
|
2470
|
-
|
|
2471
|
-
|
|
1018
|
+
const sentInitial = useRef3(false);
|
|
1019
|
+
useEffect4(() => {
|
|
1020
|
+
if (!transport) return;
|
|
1021
|
+
let alive = true;
|
|
1022
|
+
const sendInitial = () => {
|
|
1023
|
+
const prompt = optsRef.current.initialPrompt;
|
|
1024
|
+
if (!alive || !prompt || sentInitial.current) return;
|
|
1025
|
+
sentInitial.current = true;
|
|
1026
|
+
void sendRef.current(prompt);
|
|
1027
|
+
};
|
|
1028
|
+
if (opts.threadId) void runNow({ messages: [] }, true).then(sendInitial);
|
|
1029
|
+
else setTimeout(sendInitial, 0);
|
|
1030
|
+
return () => {
|
|
1031
|
+
alive = false;
|
|
1032
|
+
ctrl.current?.abort();
|
|
1033
|
+
};
|
|
2472
1034
|
}, [transport]);
|
|
2473
1035
|
const pendingResume = () => [
|
|
2474
1036
|
...ref.current.permissions.filter((p) => !answers.current.has(p.id)).map((p) => ({ interruptId: p.id, status: "cancelled" })),
|
|
2475
1037
|
...[...answers.current.entries()].map(([interruptId, a]) => ({ interruptId, ...a }))
|
|
2476
1038
|
];
|
|
1039
|
+
const sendRef = useRef3(async () => {
|
|
1040
|
+
});
|
|
2477
1041
|
const steerOn = () => optsRef.current.steer ?? ref.current.agentState.caps?.steer === true;
|
|
2478
|
-
const send =
|
|
1042
|
+
const send = useCallback(
|
|
2479
1043
|
async (text, attachments = [], _extra = {}) => {
|
|
2480
1044
|
if (!transportRef.current) return;
|
|
2481
1045
|
if (ref.current.busy) {
|
|
@@ -2490,7 +1054,8 @@ function usePilot(transport, opts = {}) {
|
|
|
2490
1054
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2491
1055
|
[commit, runNow]
|
|
2492
1056
|
);
|
|
2493
|
-
|
|
1057
|
+
sendRef.current = (text) => send(text);
|
|
1058
|
+
const sendNew = useCallback(
|
|
2494
1059
|
async (text, attachments, tries = 0) => {
|
|
2495
1060
|
const resume = pendingResume();
|
|
2496
1061
|
answers.current.clear();
|
|
@@ -2517,7 +1082,7 @@ function usePilot(transport, opts = {}) {
|
|
|
2517
1082
|
const attachments = queued.flatMap((q) => q.attachments ?? []);
|
|
2518
1083
|
void sendNew(text, attachments, Math.max(...queued.map((q) => q.tries)));
|
|
2519
1084
|
};
|
|
2520
|
-
const stop =
|
|
1085
|
+
const stop = useCallback(() => {
|
|
2521
1086
|
const run = liveRun.current ?? (ref.current.busy ? ref.current.runId : null);
|
|
2522
1087
|
liveRun.current = null;
|
|
2523
1088
|
ctrl.current?.abort();
|
|
@@ -2530,14 +1095,14 @@ function usePilot(transport, opts = {}) {
|
|
|
2530
1095
|
}).catch(() => {
|
|
2531
1096
|
});
|
|
2532
1097
|
}, [commit, threadId]);
|
|
2533
|
-
const retry =
|
|
1098
|
+
const retry = useCallback(() => {
|
|
2534
1099
|
const s = ref.current;
|
|
2535
1100
|
const last = lastUserTurn(s.turns);
|
|
2536
1101
|
if (!last || s.busy) return;
|
|
2537
1102
|
commit(dropLastExchange(s));
|
|
2538
1103
|
void send(last.text, last.attachments ?? []);
|
|
2539
1104
|
}, [commit, send]);
|
|
2540
|
-
const sendAnswersIfComplete =
|
|
1105
|
+
const sendAnswersIfComplete = useCallback(() => {
|
|
2541
1106
|
const open = ref.current.permissions.filter((p) => !answers.current.has(p.id));
|
|
2542
1107
|
if (open.length || !answers.current.size || ref.current.busy) return;
|
|
2543
1108
|
const resume = [...answers.current.entries()].map(([interruptId, a]) => ({ interruptId, ...a }));
|
|
@@ -2545,18 +1110,18 @@ function usePilot(transport, opts = {}) {
|
|
|
2545
1110
|
commit(beginSend(ref.current, "", []));
|
|
2546
1111
|
void runNow({ messages: [], resume });
|
|
2547
1112
|
}, [commit, runNow]);
|
|
2548
|
-
const respondPermission =
|
|
1113
|
+
const respondPermission = useCallback(
|
|
2549
1114
|
(id, approved) => {
|
|
2550
1115
|
answers.current.set(id, { status: "resolved", payload: { approved } });
|
|
2551
1116
|
sendAnswersIfComplete();
|
|
2552
1117
|
},
|
|
2553
1118
|
[sendAnswersIfComplete]
|
|
2554
1119
|
);
|
|
2555
|
-
const recordDecision =
|
|
1120
|
+
const recordDecision = useCallback(
|
|
2556
1121
|
(id, status, asked) => commit(resolvePermission(ref.current, id, status, asked)),
|
|
2557
1122
|
[commit]
|
|
2558
1123
|
);
|
|
2559
|
-
const expirePermission =
|
|
1124
|
+
const expirePermission = useCallback(
|
|
2560
1125
|
(id) => {
|
|
2561
1126
|
if (!ref.current.permissions.some((p) => p.id === id)) return;
|
|
2562
1127
|
answers.current.set(id, { status: "cancelled" });
|
|
@@ -2565,9 +1130,9 @@ function usePilot(transport, opts = {}) {
|
|
|
2565
1130
|
},
|
|
2566
1131
|
[commit, sendAnswersIfComplete]
|
|
2567
1132
|
);
|
|
2568
|
-
const [loadingOlder, setLoadingOlder] =
|
|
2569
|
-
const loadingRef =
|
|
2570
|
-
const loadOlder =
|
|
1133
|
+
const [loadingOlder, setLoadingOlder] = useState7(false);
|
|
1134
|
+
const loadingRef = useRef3(false);
|
|
1135
|
+
const loadOlder = useCallback(async () => {
|
|
2571
1136
|
const fn = optsRef.current.loadOlder;
|
|
2572
1137
|
const h = ref.current.history;
|
|
2573
1138
|
if (!fn || !h?.hasMoreBefore || loadingRef.current) return;
|
|
@@ -2584,7 +1149,7 @@ function usePilot(transport, opts = {}) {
|
|
|
2584
1149
|
setLoadingOlder(false);
|
|
2585
1150
|
}
|
|
2586
1151
|
}, [commit]);
|
|
2587
|
-
const stopSubagent =
|
|
1152
|
+
const stopSubagent = useCallback(
|
|
2588
1153
|
async (taskId) => {
|
|
2589
1154
|
const t = transportRef.current;
|
|
2590
1155
|
if (!t) return;
|
|
@@ -2598,72 +1163,76 @@ function usePilot(transport, opts = {}) {
|
|
|
2598
1163
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
2599
1164
|
[commit, runNow]
|
|
2600
1165
|
);
|
|
2601
|
-
const continueRun =
|
|
1166
|
+
const continueRun = useCallback(async () => {
|
|
2602
1167
|
const cut = ref.current.cutRun;
|
|
2603
1168
|
if (!cut || ref.current.busy || !transportRef.current) return;
|
|
2604
1169
|
commit(beginSend(ref.current, "", []));
|
|
2605
1170
|
await runNow({ messages: [], forwardedProps: { continueRun: cut.runId } });
|
|
2606
1171
|
}, [commit, runNow]);
|
|
2607
|
-
const refresh =
|
|
1172
|
+
const refresh = useCallback(() => runNow({ messages: [] }, true), [runNow]);
|
|
2608
1173
|
const canSteer = Boolean(transport) && (opts.steer ?? state.agentState.caps?.steer === true);
|
|
2609
|
-
const subagents =
|
|
2610
|
-
return { state, threadId, send, stop, retry, respondPermission, recordDecision, expirePermission, canSteer, loadOlder, loadingOlder, subagents, stopSubagent, refresh, continueRun };
|
|
1174
|
+
const subagents = useMemo2(() => subagentsOf(state.agentState), [state.agentState]);
|
|
1175
|
+
return { state, threadId, send, stop, retry, respondPermission, recordDecision, expirePermission, canSteer, loadOlder, loadingOlder, subagents, stopSubagent, refresh, reconnect: refresh, continueRun, subscribe, onTurn };
|
|
2611
1176
|
}
|
|
2612
1177
|
|
|
2613
1178
|
// src/react/Piloto.tsx
|
|
2614
|
-
import { Fragment as
|
|
2615
|
-
var useIsoLayoutEffect = typeof window === "undefined" ?
|
|
1179
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1180
|
+
var useIsoLayoutEffect = typeof window === "undefined" ? useEffect5 : useLayoutEffect;
|
|
2616
1181
|
var ANCHOR_GAP = 24;
|
|
2617
|
-
var Piloto =
|
|
2618
|
-
const { transport, pilot: external, locale = "es", theme = "light", features = {}
|
|
1182
|
+
var Piloto = forwardRef(function Piloto2(props, handle) {
|
|
1183
|
+
const { transport, pilot: external, locale = "es", theme = "light", features = {} } = props;
|
|
2619
1184
|
const own = usePilot(external ? null : transport, features.steer === void 0 ? props : { ...props, steer: features.steer });
|
|
2620
1185
|
const pilot = external ?? own;
|
|
2621
1186
|
const { state } = pilot;
|
|
2622
1187
|
const { turns, busy, error, notice, permissions, olderCount } = state;
|
|
2623
|
-
const
|
|
2624
|
-
|
|
1188
|
+
const plugins = useMemo3(() => resolvePlugins(props.plugins), [props.plugins]);
|
|
1189
|
+
useEffect5(() => {
|
|
1190
|
+
if (isDev()) for (const w of plugins.warnings) warnOnce(w);
|
|
1191
|
+
}, [plugins]);
|
|
1192
|
+
const strings = useMemo3(() => ({ ...locale === "en" ? STRINGS_EN : STRINGS_ES, ...plugins.strings }), [locale, plugins]);
|
|
1193
|
+
const config = useMemo3(
|
|
2625
1194
|
() => ({
|
|
2626
1195
|
strings,
|
|
2627
|
-
toolVerbs: { ...locale === "en" ? TOOL_VERBS_EN : TOOL_VERBS_ES, ...
|
|
2628
|
-
toolIcons:
|
|
2629
|
-
formatUserText:
|
|
1196
|
+
toolVerbs: { ...locale === "en" ? TOOL_VERBS_EN : TOOL_VERBS_ES, ...plugins.verbs },
|
|
1197
|
+
toolIcons: plugins.icons,
|
|
1198
|
+
formatUserText: plugins.formatUserText ? (x) => plugins.formatUserText(cleanUserText(x)) : cleanUserText,
|
|
2630
1199
|
theme,
|
|
2631
1200
|
skin: props.skin ?? "ghosty",
|
|
2632
|
-
markdown:
|
|
1201
|
+
markdown: plugins.markdown
|
|
2633
1202
|
}),
|
|
2634
|
-
[strings, locale,
|
|
1203
|
+
[strings, locale, plugins, theme, props.skin]
|
|
2635
1204
|
);
|
|
2636
1205
|
const t = strings;
|
|
2637
|
-
const [ownRefs, setOwnRefs] =
|
|
1206
|
+
const [ownRefs, setOwnRefs] = useState8([]);
|
|
2638
1207
|
const refs = props.references ?? ownRefs;
|
|
2639
|
-
const refsRef =
|
|
1208
|
+
const refsRef = useRef4(refs);
|
|
2640
1209
|
refsRef.current = refs;
|
|
2641
|
-
const setRefs =
|
|
1210
|
+
const setRefs = useCallback2(
|
|
2642
1211
|
(next) => {
|
|
2643
1212
|
if (!props.references) setOwnRefs(next);
|
|
2644
1213
|
props.onReferencesChange?.(next);
|
|
2645
1214
|
},
|
|
2646
1215
|
[props.references, props.onReferencesChange]
|
|
2647
1216
|
);
|
|
2648
|
-
const composerBox =
|
|
1217
|
+
const composerBox = useRef4(null);
|
|
2649
1218
|
const draftText = typeof props.draft === "string" ? props.draft : props.draft?.text;
|
|
2650
1219
|
const draftKey = typeof props.draft === "object" && props.draft ? props.draft.key : void 0;
|
|
2651
|
-
const [draft, setDraftState] =
|
|
2652
|
-
const draftSeen =
|
|
2653
|
-
|
|
1220
|
+
const [draft, setDraftState] = useState8(() => ({ text: draftText ?? "", n: 0 }));
|
|
1221
|
+
const draftSeen = useRef4(`${draftText}\0${draftKey}`);
|
|
1222
|
+
useEffect5(() => {
|
|
2654
1223
|
const id = `${draftText}\0${draftKey}`;
|
|
2655
1224
|
if (draftText == null || id === draftSeen.current) return;
|
|
2656
1225
|
draftSeen.current = id;
|
|
2657
1226
|
setDraftState((d) => ({ text: draftText, n: d.n + 1 }));
|
|
2658
1227
|
}, [draftText, draftKey]);
|
|
2659
1228
|
const returned = state.returnedDraft;
|
|
2660
|
-
|
|
1229
|
+
useEffect5(() => {
|
|
2661
1230
|
if (!returned) return;
|
|
2662
1231
|
const typed = composerBox.current?.querySelector("textarea")?.value ?? "";
|
|
2663
1232
|
const text = [returned.text, typed].filter((x) => x.trim()).join("\n\n");
|
|
2664
1233
|
setDraftState((d) => ({ text, n: d.n + 1 }));
|
|
2665
1234
|
}, [returned?.n]);
|
|
2666
|
-
const send =
|
|
1235
|
+
const send = useCallback2(
|
|
2667
1236
|
(text, attachments = []) => {
|
|
2668
1237
|
const current = refsRef.current;
|
|
2669
1238
|
const full = applyReferences(text, current);
|
|
@@ -2672,22 +1241,82 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2672
1241
|
},
|
|
2673
1242
|
[pilot, setRefs]
|
|
2674
1243
|
);
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
1244
|
+
const composerHandle = useRef4(null);
|
|
1245
|
+
const focus = useCallback2(() => composerBox.current?.querySelector("textarea")?.focus({ preventScroll: true }), []);
|
|
1246
|
+
const addReference = useCallback2(
|
|
1247
|
+
(r) => {
|
|
1248
|
+
const current = refsRef.current;
|
|
1249
|
+
if (!current.some((x) => x.id === r.id)) setRefs([...current, r]);
|
|
1250
|
+
requestAnimationFrame(focus);
|
|
1251
|
+
},
|
|
1252
|
+
[setRefs, focus]
|
|
1253
|
+
);
|
|
1254
|
+
const setDraft = useCallback2((text) => setDraftState((d) => ({ text, n: d.n + 1 })), []);
|
|
1255
|
+
const addAttachments = useCallback2((items) => composerHandle.current?.addAttachments(items), []);
|
|
1256
|
+
const actions = { pilot, send, addReference, addAttachments, setDraft, focus };
|
|
1257
|
+
useImperativeHandle(handle, () => actions, [pilot, send, addReference, addAttachments, setDraft, focus]);
|
|
1258
|
+
const ctx = { ...actions, agentState: state.agentState, strings, plugins: plugins.list };
|
|
1259
|
+
const ctxRef = useRef4(ctx);
|
|
1260
|
+
ctxRef.current = ctx;
|
|
1261
|
+
const pluginsRef = useRef4(plugins);
|
|
1262
|
+
pluginsRef.current = plugins;
|
|
1263
|
+
const unattended = useRef4(/* @__PURE__ */ new Set());
|
|
1264
|
+
useEffect5(
|
|
1265
|
+
() => pilot.subscribe?.((event) => {
|
|
1266
|
+
const e = event;
|
|
1267
|
+
const r = pluginsRef.current;
|
|
1268
|
+
const handlers = [...r.events[e.type] ?? [], ...e.type === "CUSTOM" && e.name ? r.events[e.name] ?? [] : [], ...r.events["*"] ?? []];
|
|
1269
|
+
for (const h of handlers) {
|
|
1270
|
+
try {
|
|
1271
|
+
h.value(e, ctxRef.current);
|
|
1272
|
+
} catch (err) {
|
|
1273
|
+
console.error(`[ghostykit] el plugin \xAB${h.plugin}\xBB fall\xF3 con ${e.type}${e.name ? ` ${e.name}` : ""}`, err);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
if (e.type === "CUSTOM" && e.name && isDev() && !BUILTIN_CUSTOM.has(e.name) && !r.events[e.name] && !r.customRenders[e.name] && !unattended.current.has(e.name)) {
|
|
1277
|
+
const declared = r.list.some((p) => p.requires?.events?.includes(e.name));
|
|
1278
|
+
if (!declared) {
|
|
1279
|
+
unattended.current.add(e.name);
|
|
1280
|
+
warnOnce(`Ning\xFAn plugin atiende CUSTOM \xAB${e.name}\xBB.`);
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
2686
1283
|
}),
|
|
2687
|
-
[
|
|
1284
|
+
[pilot.subscribe]
|
|
2688
1285
|
);
|
|
2689
|
-
const
|
|
2690
|
-
|
|
1286
|
+
const seenState = useRef4({});
|
|
1287
|
+
useEffect5(() => {
|
|
1288
|
+
const r = pluginsRef.current;
|
|
1289
|
+
for (const [key, handlers] of Object.entries(r.state)) {
|
|
1290
|
+
const value = state.agentState[key];
|
|
1291
|
+
if (value === seenState.current[key]) continue;
|
|
1292
|
+
seenState.current[key] = value;
|
|
1293
|
+
if (value === void 0) continue;
|
|
1294
|
+
for (const h of handlers) {
|
|
1295
|
+
try {
|
|
1296
|
+
h.value(value, ctxRef.current);
|
|
1297
|
+
} catch (err) {
|
|
1298
|
+
console.error(`[ghostykit] el plugin \xAB${h.plugin}\xBB fall\xF3 con state.${key}`, err);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
}
|
|
1302
|
+
}, [state.agentState, plugins]);
|
|
1303
|
+
useEffect5(
|
|
1304
|
+
() => pilot.onTurn?.((e) => {
|
|
1305
|
+
const r = pluginsRef.current;
|
|
1306
|
+
const run = (plugin, fn) => {
|
|
1307
|
+
try {
|
|
1308
|
+
fn();
|
|
1309
|
+
} catch (err) {
|
|
1310
|
+
console.error(`[ghostykit] el plugin \xAB${plugin}\xBB fall\xF3 al ${e.type === "start" ? "empezar" : "terminar"} el turno`, err);
|
|
1311
|
+
}
|
|
1312
|
+
};
|
|
1313
|
+
if (e.type === "start") for (const h of r.turnStart) run(h.plugin, () => h.value(ctxRef.current));
|
|
1314
|
+
else for (const h of r.turnDone) run(h.plugin, () => h.value(e.info, ctxRef.current));
|
|
1315
|
+
}),
|
|
1316
|
+
[pilot.onTurn]
|
|
1317
|
+
);
|
|
1318
|
+
const [held, setHeld] = useState8({});
|
|
1319
|
+
const heldRef = useRef4(held);
|
|
2691
1320
|
heldRef.current = held;
|
|
2692
1321
|
const releaseHeld = (id) => setHeld(({ [id]: _, ...rest }) => rest);
|
|
2693
1322
|
const respond = (id, approved) => {
|
|
@@ -2703,15 +1332,15 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2703
1332
|
releaseHeld(id);
|
|
2704
1333
|
};
|
|
2705
1334
|
const cards = [...permissions, ...Object.values(held).filter((h) => !permissions.some((p) => p.id === h.id))];
|
|
2706
|
-
const scroller =
|
|
2707
|
-
const column =
|
|
2708
|
-
const spacer =
|
|
2709
|
-
const following =
|
|
2710
|
-
const touchY =
|
|
2711
|
-
const [atBottom, setAtBottom] =
|
|
1335
|
+
const scroller = useRef4(null);
|
|
1336
|
+
const column = useRef4(null);
|
|
1337
|
+
const spacer = useRef4(null);
|
|
1338
|
+
const following = useRef4(true);
|
|
1339
|
+
const touchY = useRef4(null);
|
|
1340
|
+
const [atBottom, setAtBottom] = useState8(true);
|
|
2712
1341
|
const message = (n) => scroller.current?.querySelector(`[data-turn="${n}"]`) ?? null;
|
|
2713
|
-
const olderSeen =
|
|
2714
|
-
const heightBefore =
|
|
1342
|
+
const olderSeen = useRef4(olderCount);
|
|
1343
|
+
const heightBefore = useRef4(0);
|
|
2715
1344
|
useIsoLayoutEffect(() => {
|
|
2716
1345
|
const el = scroller.current;
|
|
2717
1346
|
if (el && olderCount > olderSeen.current && heightBefore.current) el.scrollTop += el.scrollHeight - heightBefore.current;
|
|
@@ -2722,8 +1351,8 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2722
1351
|
heightBefore.current = scroller.current?.scrollHeight ?? 0;
|
|
2723
1352
|
void pilot.loadOlder();
|
|
2724
1353
|
};
|
|
2725
|
-
const placed =
|
|
2726
|
-
|
|
1354
|
+
const placed = useRef4(false);
|
|
1355
|
+
useEffect5(() => {
|
|
2727
1356
|
if (placed.current || turns.length === 0) return;
|
|
2728
1357
|
placed.current = true;
|
|
2729
1358
|
const el = scroller.current;
|
|
@@ -2738,16 +1367,20 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2738
1367
|
}
|
|
2739
1368
|
}
|
|
2740
1369
|
const mine = mineIndex >= 0 ? turns[mineIndex] : null;
|
|
2741
|
-
const mineSeen =
|
|
2742
|
-
const [anchor, setAnchor] =
|
|
2743
|
-
|
|
1370
|
+
const mineSeen = useRef4(mine);
|
|
1371
|
+
const [anchor, setAnchor] = useState8(null);
|
|
1372
|
+
useEffect5(() => {
|
|
2744
1373
|
if (mine === mineSeen.current) return;
|
|
2745
1374
|
mineSeen.current = mine;
|
|
1375
|
+
if (!state.turnStartedAt) {
|
|
1376
|
+
following.current = true;
|
|
1377
|
+
return;
|
|
1378
|
+
}
|
|
2746
1379
|
if (mine) setAnchor(mineIndex - olderCount);
|
|
2747
1380
|
following.current = true;
|
|
2748
1381
|
}, [mine, mineIndex]);
|
|
2749
1382
|
const gapAbove = (a) => anchor === -olderCount ? a.offsetTop : ANCHOR_GAP;
|
|
2750
|
-
const measureSpacer =
|
|
1383
|
+
const measureSpacer = useCallback2(() => {
|
|
2751
1384
|
const sc = scroller.current;
|
|
2752
1385
|
const sp = spacer.current;
|
|
2753
1386
|
if (!sc || !sp) return;
|
|
@@ -2765,7 +1398,7 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2765
1398
|
const a = anchor != null ? message(anchor) : null;
|
|
2766
1399
|
if (sc && a) sc.scrollTo({ top: a.offsetTop - gapAbove(a), behavior: "smooth" });
|
|
2767
1400
|
}, [anchor, measureSpacer]);
|
|
2768
|
-
|
|
1401
|
+
useEffect5(() => {
|
|
2769
1402
|
const col = column.current;
|
|
2770
1403
|
const sc = scroller.current;
|
|
2771
1404
|
if (!col || !sc || typeof ResizeObserver === "undefined") return;
|
|
@@ -2795,13 +1428,14 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2795
1428
|
const toolRunning = busy && last?.role === "assistant" && (last.tools ?? []).some(isRunning);
|
|
2796
1429
|
const empty = turns.length === 0 && !busy;
|
|
2797
1430
|
const placeholder = props.placeholder ?? (props.agentName ? t.placeholder(props.agentName) : t.placeholderDefault);
|
|
2798
|
-
const
|
|
1431
|
+
const { upload, transcribe, voiceNoteText } = plugins.attachments;
|
|
1432
|
+
const showFiles = features.attachments ?? Boolean(upload);
|
|
2799
1433
|
const pointedRefs = refs.filter((r) => r.prompt);
|
|
2800
1434
|
const plainRefs = refs.filter((r) => !r.prompt);
|
|
2801
1435
|
const removeRef = (id) => setRefs(refsRef.current.filter((r) => r.id !== id));
|
|
2802
|
-
const composer = /* @__PURE__ */
|
|
2803
|
-
/* @__PURE__ */
|
|
2804
|
-
/* @__PURE__ */
|
|
1436
|
+
const composer = /* @__PURE__ */ jsxs6("div", { ref: composerBox, children: [
|
|
1437
|
+
/* @__PURE__ */ jsx8(ReferenceChips, { references: pointedRefs, onRemove: removeRef, onActivate: props.onReferenceClick }),
|
|
1438
|
+
/* @__PURE__ */ jsx8(
|
|
2805
1439
|
Composer,
|
|
2806
1440
|
{
|
|
2807
1441
|
initialValue: draft.text,
|
|
@@ -2811,156 +1445,232 @@ var Piloto = forwardRef3(function Piloto2(props, handle) {
|
|
|
2811
1445
|
canSteer: pilot.canSteer,
|
|
2812
1446
|
placeholder,
|
|
2813
1447
|
attachments: showFiles,
|
|
2814
|
-
upload
|
|
2815
|
-
transcribe
|
|
2816
|
-
voiceNoteText
|
|
1448
|
+
upload,
|
|
1449
|
+
transcribe,
|
|
1450
|
+
voiceNoteText,
|
|
2817
1451
|
references: plainRefs,
|
|
2818
1452
|
onRemoveReference: removeRef,
|
|
2819
1453
|
onActivateReference: props.onReferenceClick,
|
|
2820
|
-
extras:
|
|
1454
|
+
extras: plugins.composerActions.length ? /* @__PURE__ */ jsx8(Views, { items: plugins.composerActions, ctx, styled: plugins.ghostykitStyled, inline: true }) : void 0,
|
|
1455
|
+
extrasEnd: plugins.composerActionsEnd.length ? /* @__PURE__ */ jsx8(Views, { items: plugins.composerActionsEnd, ctx, styled: plugins.ghostykitStyled, inline: true }) : void 0,
|
|
1456
|
+
handleRef: composerHandle
|
|
2821
1457
|
},
|
|
2822
1458
|
draft.n
|
|
2823
1459
|
)
|
|
2824
1460
|
] });
|
|
2825
|
-
const withPanel = (chat) =>
|
|
2826
|
-
/* @__PURE__ */
|
|
2827
|
-
|
|
1461
|
+
const withPanel = (chat) => plugins.sidePanel.length ? /* @__PURE__ */ jsxs6("div", { className: "flex min-h-0 flex-1 flex-row", children: [
|
|
1462
|
+
/* @__PURE__ */ jsx8("div", { className: "relative flex min-h-0 min-w-0 flex-1 flex-col", children: chat }),
|
|
1463
|
+
/* @__PURE__ */ jsx8(Views, { items: plugins.sidePanel, ctx, styled: plugins.ghostykitStyled, className: "flex min-h-0 shrink-0" })
|
|
2828
1464
|
] }) : chat;
|
|
2829
|
-
const aboveComposer =
|
|
2830
|
-
const
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
1465
|
+
const aboveComposer = plugins.composerAbove.length ? /* @__PURE__ */ jsx8(Views, { items: plugins.composerAbove, ctx, styled: plugins.ghostykitStyled }) : null;
|
|
1466
|
+
const belowComposer = plugins.composerBelow.length ? /* @__PURE__ */ jsx8(Views, { items: plugins.composerBelow, ctx, styled: plugins.ghostykitStyled }) : null;
|
|
1467
|
+
const header = plugins.header.length ? /* @__PURE__ */ jsx8(Views, { items: plugins.header, ctx, styled: plugins.ghostykitStyled, inline: true }) : null;
|
|
1468
|
+
const mark = (plugin) => pluginAttrs(plugin, plugins.ghostykitStyled);
|
|
1469
|
+
const Empty = plugins.empty?.value;
|
|
1470
|
+
const Waiting = plugins.waiting?.value;
|
|
1471
|
+
const renderDeliveries = (turn, live) => {
|
|
1472
|
+
const custom = (turn.custom ?? []).map((entry, i) => {
|
|
1473
|
+
const owner = plugins.customRenders[entry.name];
|
|
1474
|
+
if (!owner) return null;
|
|
1475
|
+
const C = owner.value;
|
|
1476
|
+
return /* @__PURE__ */ jsx8("div", { ...mark(owner.plugin), children: /* @__PURE__ */ jsx8(C, { ctx, entry, turn, live }) }, `c${i}`);
|
|
1477
|
+
});
|
|
1478
|
+
const extras = plugins.messageAssistant.map((o, i) => /* @__PURE__ */ jsx8("div", { ...mark(o.plugin), children: /* @__PURE__ */ jsx8(o.value, { ctx, turn, live }) }, `a${i}`));
|
|
1479
|
+
return custom.some(Boolean) || extras.length ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1480
|
+
custom,
|
|
1481
|
+
extras
|
|
1482
|
+
] }) : null;
|
|
1483
|
+
};
|
|
1484
|
+
const renderTools = (turn, live) => {
|
|
1485
|
+
const views = (turn.tools ?? []).flatMap((tool) => {
|
|
1486
|
+
const owner = plugins.toolRenders[tool.title ?? ""] ?? (tool.kind ? plugins.toolRenders[tool.kind] : void 0);
|
|
1487
|
+
if (!owner) return [];
|
|
1488
|
+
const C = owner.value;
|
|
1489
|
+
return [
|
|
1490
|
+
/* @__PURE__ */ jsx8("div", { ...mark(owner.plugin), children: /* @__PURE__ */ jsx8(C, { ctx, tool, turn, live }) }, tool.id)
|
|
1491
|
+
];
|
|
1492
|
+
});
|
|
1493
|
+
return views.length ? /* @__PURE__ */ jsx8("div", { className: "mb-3 flex flex-col gap-2", children: views }) : null;
|
|
1494
|
+
};
|
|
1495
|
+
const renderBefore = plugins.messageBefore.length ? (turn, live) => /* @__PURE__ */ jsx8(Fragment4, { children: plugins.messageBefore.map((o, i) => /* @__PURE__ */ jsx8("div", { ...mark(o.plugin), children: /* @__PURE__ */ jsx8(o.value, { ctx, turn, live }) }, i)) }) : void 0;
|
|
1496
|
+
const blockLangs = Object.keys(plugins.blockRenders);
|
|
1497
|
+
const blocks = blockLangs.length ? {
|
|
1498
|
+
langs: blockLangs,
|
|
1499
|
+
render: (list, turn, live) => /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-col gap-2", children: list.map((block, i) => {
|
|
1500
|
+
const owner = plugins.blockRenders[block.lang];
|
|
1501
|
+
const C = owner.value;
|
|
1502
|
+
return /* @__PURE__ */ jsx8("div", { ...mark(owner.plugin), children: /* @__PURE__ */ jsx8(C, { ctx, block, turn, live }) }, i);
|
|
1503
|
+
}) })
|
|
1504
|
+
} : void 0;
|
|
1505
|
+
const wrapAll = (tree) => plugins.wraps.reduceRight((inner, { value: W }) => /* @__PURE__ */ jsx8(W, { ctx, children: inner }), tree);
|
|
1506
|
+
const permissionCards = cards.map((p) => /* @__PURE__ */ jsx8(ConfirmCard, { request: p, onRespond: respond, onSettled: settle, onExpire: pilot.expirePermission }, p.id));
|
|
1507
|
+
return /* @__PURE__ */ jsx8(PilotoContext.Provider, { value: config, children: wrapAll(
|
|
1508
|
+
/* @__PURE__ */ jsx8(
|
|
2856
1509
|
"div",
|
|
2857
1510
|
{
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
1511
|
+
...rootProps(theme, props.skin),
|
|
1512
|
+
"data-busy": busy || void 0,
|
|
1513
|
+
className: `piloto ${plugins.className} ${props.className ?? ""}`,
|
|
1514
|
+
style: Object.keys(plugins.vars).length ? { ...plugins.vars, ...props.style } : props.style,
|
|
1515
|
+
children: withPanel(empty ? (
|
|
1516
|
+
// Un hilo vacío enseña lo mismo que la portada: la cara, el saludo, la caja y por dónde
|
|
1517
|
+
// empezar. Si no cabe (panel bajo), se desplaza: `safe center` nunca empuja nada fuera.
|
|
1518
|
+
/* @__PURE__ */ jsxs6("div", { className: "gs-scroll flex min-h-0 flex-1 flex-col items-center justify-center overflow-y-auto px-4 pb-[10vh] [justify-content:safe_center]", children: [
|
|
1519
|
+
header && /* @__PURE__ */ jsx8("div", { className: "absolute right-4 top-3 flex gap-2", children: header }),
|
|
1520
|
+
Empty ? /* @__PURE__ */ jsx8("div", { ...mark(plugins.empty.plugin), children: /* @__PURE__ */ jsx8(Empty, { ctx }) }) : /* @__PURE__ */ jsxs6("div", { className: "mb-6 flex flex-col items-center", children: [
|
|
1521
|
+
props.avatar && /* @__PURE__ */ jsx8("div", { className: "mb-3", children: props.avatar }),
|
|
1522
|
+
props.welcome && // Un saludo largo (una explicación del piloto) baja a letra de lectura.
|
|
1523
|
+
/* @__PURE__ */ jsx8(
|
|
1524
|
+
"h1",
|
|
1525
|
+
{
|
|
1526
|
+
className: typeof props.welcome === "string" && props.welcome.length > 60 ? "max-w-xl text-center text-base font-medium leading-6 text-metal" : "text-center text-3xl font-extrabold tracking-tight text-dark",
|
|
1527
|
+
children: props.welcome
|
|
1528
|
+
}
|
|
1529
|
+
)
|
|
1530
|
+
] }),
|
|
1531
|
+
/* @__PURE__ */ jsxs6("div", { className: "w-full max-w-3xl", children: [
|
|
1532
|
+
aboveComposer,
|
|
1533
|
+
composer,
|
|
1534
|
+
belowComposer,
|
|
1535
|
+
props.suggestions && /* @__PURE__ */ jsx8(Suggestions, { items: props.suggestions, onPick: (s) => send(s), onPrefill: (s) => setDraftState((d) => ({ text: s, n: d.n + 1 })) })
|
|
1536
|
+
] })
|
|
1537
|
+
] })
|
|
1538
|
+
) : /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1539
|
+
header && /* @__PURE__ */ jsx8("div", { className: "flex shrink-0 justify-end gap-2 px-4 pt-3 sm:px-6", children: header }),
|
|
1540
|
+
/* @__PURE__ */ jsxs6(
|
|
1541
|
+
"div",
|
|
1542
|
+
{
|
|
1543
|
+
ref: scroller,
|
|
1544
|
+
onScroll,
|
|
1545
|
+
onWheel: (e) => e.deltaY < 0 && release(),
|
|
1546
|
+
onTouchStart: (e) => {
|
|
1547
|
+
touchY.current = e.touches[0]?.clientY ?? null;
|
|
1548
|
+
},
|
|
1549
|
+
onTouchMove: (e) => {
|
|
1550
|
+
const y = e.touches[0]?.clientY;
|
|
1551
|
+
if (touchY.current != null && y != null && y > touchY.current + 4) release();
|
|
1552
|
+
},
|
|
1553
|
+
onKeyDown: (e) => ["ArrowUp", "PageUp", "Home"].includes(e.key) && release(),
|
|
1554
|
+
className: "gs-scroll relative min-h-0 flex-1 overflow-y-auto overflow-x-hidden",
|
|
1555
|
+
children: [
|
|
1556
|
+
/* @__PURE__ */ jsxs6("div", { ref: column, className: "mx-auto flex w-full max-w-[784px] flex-col gap-6 px-4 py-8 sm:px-6", children: [
|
|
1557
|
+
plugins.aboveThread.length > 0 && /* @__PURE__ */ jsx8(Views, { items: plugins.aboveThread, ctx, styled: plugins.ghostykitStyled }),
|
|
1558
|
+
state.history?.hasMoreBefore && (external || props.loadOlder) && /* @__PURE__ */ jsx8(
|
|
1559
|
+
"button",
|
|
1560
|
+
{
|
|
1561
|
+
type: "button",
|
|
1562
|
+
onClick: loadOlder,
|
|
1563
|
+
disabled: pilot.loadingOlder,
|
|
1564
|
+
className: "self-center rounded-full border border-border-primary px-3 py-1 text-sm text-text-secondary transition hover:text-text-primary disabled:opacity-60",
|
|
1565
|
+
children: pilot.loadingOlder ? t.loadingOlder : t.loadOlder
|
|
1566
|
+
}
|
|
1567
|
+
),
|
|
1568
|
+
turns.map((turn, i) => {
|
|
1569
|
+
const isLast = i === turns.length - 1;
|
|
1570
|
+
const live = busy && isLast;
|
|
1571
|
+
return /* @__PURE__ */ jsxs6("div", { "data-turn": i - olderCount, children: [
|
|
1572
|
+
turn.role === "user" ? /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
1573
|
+
/* @__PURE__ */ jsx8(UserBubble, { turn }),
|
|
1574
|
+
plugins.messageUser.map((o, j) => /* @__PURE__ */ jsx8("div", { ...mark(o.plugin), children: /* @__PURE__ */ jsx8(o.value, { ctx, turn }) }, j))
|
|
1575
|
+
] }) : /* @__PURE__ */ jsx8(
|
|
1576
|
+
AgentBubble,
|
|
1577
|
+
{
|
|
1578
|
+
turn,
|
|
1579
|
+
live,
|
|
1580
|
+
onRetry: isLast && features.retry !== false ? pilot.retry : void 0,
|
|
1581
|
+
onOption: isLast && !busy && features.replyOptions !== false ? (text) => send(text) : void 0,
|
|
1582
|
+
showUsage: features.usage !== false,
|
|
1583
|
+
showCopy: features.copy !== false,
|
|
1584
|
+
showDuration: features.duration !== false,
|
|
1585
|
+
renderDeliveries,
|
|
1586
|
+
renderTools,
|
|
1587
|
+
renderBefore,
|
|
1588
|
+
blocks
|
|
1589
|
+
}
|
|
1590
|
+
),
|
|
1591
|
+
turn.role === "assistant" && /* @__PURE__ */ jsx8(TurnNotes, { turn })
|
|
1592
|
+
] }, i - olderCount);
|
|
1593
|
+
}),
|
|
1594
|
+
busy && state.stalled && /* @__PURE__ */ jsx8("p", { className: "text-sm text-text-tertiary", children: state.stalled.message ?? t.stalled }),
|
|
1595
|
+
state.queued.map((q, i) => (
|
|
1596
|
+
// Esperan a que termine el run vivo (el servidor no los dejó entrar): salen solos.
|
|
1597
|
+
/* @__PURE__ */ jsxs6("div", { "data-queued": true, className: "flex flex-col items-end gap-1 opacity-60", children: [
|
|
1598
|
+
/* @__PURE__ */ jsx8(UserBubble, { turn: { role: "user", text: q.text, ...q.attachments ? { attachments: q.attachments } : {} } }),
|
|
1599
|
+
/* @__PURE__ */ jsx8("span", { className: "text-xs text-text-tertiary", children: t.queued })
|
|
1600
|
+
] }, `q${i}`)
|
|
1601
|
+
)),
|
|
1602
|
+
permissionCards,
|
|
1603
|
+
busy && !toolRunning && !cards.length && (Waiting ? /* @__PURE__ */ jsx8("div", { ...mark(plugins.waiting.plugin), children: /* @__PURE__ */ jsx8(Waiting, { ctx, step: state.step, since: state.turnStartedAt }) }) : /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-1.5", children: [
|
|
1604
|
+
/* @__PURE__ */ jsx8(TypingDots, {}),
|
|
1605
|
+
/* @__PURE__ */ jsx8(WaitLabel, { since: state.turnStartedAt, step: state.step, showDuration: features.duration !== false })
|
|
1606
|
+
] })),
|
|
1607
|
+
notice && /* @__PURE__ */ jsx8("p", { className: "text-sm text-text-tertiary", children: notice }),
|
|
1608
|
+
error && /* @__PURE__ */ jsx8("p", { className: "text-sm text-text-danger", children: error })
|
|
1609
|
+
] }),
|
|
1610
|
+
/* @__PURE__ */ jsx8("div", { ref: spacer, "aria-hidden": true })
|
|
1611
|
+
]
|
|
1612
|
+
}
|
|
1613
|
+
),
|
|
1614
|
+
/* @__PURE__ */ jsxs6("div", { className: "relative mx-auto w-full max-w-[784px] px-4 pb-4 sm:px-6 sm:pb-6", children: [
|
|
1615
|
+
!atBottom && /* @__PURE__ */ jsx8(
|
|
2873
1616
|
"button",
|
|
2874
1617
|
{
|
|
2875
1618
|
type: "button",
|
|
2876
|
-
onClick:
|
|
2877
|
-
|
|
2878
|
-
className: "
|
|
2879
|
-
children:
|
|
1619
|
+
onClick: toBottom,
|
|
1620
|
+
"aria-label": t.goToLatest,
|
|
1621
|
+
className: "absolute -top-12 left-1/2 z-10 flex h-9 w-9 -translate-x-1/2 items-center justify-center rounded-full border border-border-primary bg-background-secondary text-text-secondary shadow-lg transition hover:text-text-primary",
|
|
1622
|
+
children: /* @__PURE__ */ jsx8(ArrowDown, { className: "h-4 w-4" })
|
|
2880
1623
|
}
|
|
2881
1624
|
),
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
showCopy: features.copy !== false,
|
|
2895
|
-
showDuration: features.duration !== false,
|
|
2896
|
-
renderDeliveries: slots.renderDeliveries
|
|
2897
|
-
}
|
|
2898
|
-
),
|
|
2899
|
-
turn.role === "assistant" && /* @__PURE__ */ jsx10(TurnNotes, { turn })
|
|
2900
|
-
] }, i - olderCount);
|
|
2901
|
-
}),
|
|
2902
|
-
busy && state.stalled && /* @__PURE__ */ jsx10("p", { className: "text-sm text-text-tertiary", children: state.stalled.message ?? t.stalled }),
|
|
2903
|
-
state.queued.map((q, i) => (
|
|
2904
|
-
// Esperan a que termine el run vivo (el servidor no los dejó entrar): salen solos.
|
|
2905
|
-
/* @__PURE__ */ jsxs8("div", { "data-queued": true, className: "flex flex-col items-end gap-1 opacity-60", children: [
|
|
2906
|
-
/* @__PURE__ */ jsx10(UserBubble, { turn: { role: "user", text: q.text, ...q.attachments ? { attachments: q.attachments } : {} } }),
|
|
2907
|
-
/* @__PURE__ */ jsx10("span", { className: "text-xs text-text-tertiary", children: t.queued })
|
|
2908
|
-
] }, `q${i}`)
|
|
2909
|
-
)),
|
|
2910
|
-
permissionCards,
|
|
2911
|
-
busy && !toolRunning && !cards.length && /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-1.5", children: [
|
|
2912
|
-
/* @__PURE__ */ jsx10(TypingDots, {}),
|
|
2913
|
-
/* @__PURE__ */ jsx10(WaitLabel, { since: state.turnStartedAt, step: state.step, showDuration: features.duration !== false })
|
|
1625
|
+
state.cutRun && !busy && // El servidor cortó la respuesta (deploy, caja caída): la persona decide si sigue.
|
|
1626
|
+
/* @__PURE__ */ jsxs6("div", { "data-cut-run": true, role: "status", className: "mb-2 flex items-center gap-3 rounded-2xl border border-border-primary bg-background-secondary px-3 py-2 text-sm text-text-secondary", children: [
|
|
1627
|
+
/* @__PURE__ */ jsx8("span", { className: "min-w-0 flex-1", children: state.cutRun.reason ?? t.runCut }),
|
|
1628
|
+
/* @__PURE__ */ jsx8(
|
|
1629
|
+
"button",
|
|
1630
|
+
{
|
|
1631
|
+
type: "button",
|
|
1632
|
+
onClick: () => void pilot.continueRun(),
|
|
1633
|
+
className: "shrink-0 rounded-full bg-brand-500 px-3 py-1 text-sm font-medium text-white transition hover:bg-brand-600",
|
|
1634
|
+
children: t.continueRun
|
|
1635
|
+
}
|
|
1636
|
+
)
|
|
2914
1637
|
] }),
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
]
|
|
1638
|
+
aboveComposer,
|
|
1639
|
+
composer,
|
|
1640
|
+
belowComposer
|
|
1641
|
+
] })
|
|
1642
|
+
] }))
|
|
2920
1643
|
}
|
|
2921
|
-
)
|
|
2922
|
-
|
|
2923
|
-
!atBottom && /* @__PURE__ */ jsx10(
|
|
2924
|
-
"button",
|
|
2925
|
-
{
|
|
2926
|
-
type: "button",
|
|
2927
|
-
onClick: toBottom,
|
|
2928
|
-
"aria-label": t.goToLatest,
|
|
2929
|
-
className: "absolute -top-12 left-1/2 z-10 flex h-9 w-9 -translate-x-1/2 items-center justify-center rounded-full border border-border-primary bg-background-secondary text-text-secondary shadow-lg transition hover:text-text-primary",
|
|
2930
|
-
children: /* @__PURE__ */ jsx10(ArrowDown, { className: "h-4 w-4" })
|
|
2931
|
-
}
|
|
2932
|
-
),
|
|
2933
|
-
state.cutRun && !busy && // El servidor cortó la respuesta (deploy, caja caída): la persona decide si sigue.
|
|
2934
|
-
/* @__PURE__ */ jsxs8("div", { "data-cut-run": true, role: "status", className: "mb-2 flex items-center gap-3 rounded-2xl border border-border-primary bg-background-secondary px-3 py-2 text-sm text-text-secondary", children: [
|
|
2935
|
-
/* @__PURE__ */ jsx10("span", { className: "min-w-0 flex-1", children: state.cutRun.reason ?? t.runCut }),
|
|
2936
|
-
/* @__PURE__ */ jsx10(
|
|
2937
|
-
"button",
|
|
2938
|
-
{
|
|
2939
|
-
type: "button",
|
|
2940
|
-
onClick: () => void pilot.continueRun(),
|
|
2941
|
-
className: "shrink-0 rounded-full bg-brand-500 px-3 py-1 text-sm font-medium text-white transition hover:bg-brand-600",
|
|
2942
|
-
children: t.continueRun
|
|
2943
|
-
}
|
|
2944
|
-
)
|
|
2945
|
-
] }),
|
|
2946
|
-
aboveComposer,
|
|
2947
|
-
composer
|
|
2948
|
-
] })
|
|
2949
|
-
] })) }) });
|
|
1644
|
+
)
|
|
1645
|
+
) });
|
|
2950
1646
|
});
|
|
1647
|
+
var warned = /* @__PURE__ */ new Set();
|
|
1648
|
+
function warnOnce(message) {
|
|
1649
|
+
if (warned.has(message)) return;
|
|
1650
|
+
warned.add(message);
|
|
1651
|
+
console.warn(`[ghostykit] ${message}`);
|
|
1652
|
+
}
|
|
1653
|
+
function pluginAttrs(plugin, styled) {
|
|
1654
|
+
return styled.has(plugin) ? { "data-plugin": plugin } : { "data-plugin": plugin, "data-piloto-isolate": "" };
|
|
1655
|
+
}
|
|
1656
|
+
function Views({ items, ctx, inline, className, styled }) {
|
|
1657
|
+
return /* @__PURE__ */ jsx8(Fragment4, { children: items.map(
|
|
1658
|
+
({ plugin, value: C }) => inline ? /* @__PURE__ */ jsx8("span", { ...pluginAttrs(plugin, styled), style: { display: "contents" }, children: /* @__PURE__ */ jsx8(C, { ctx }) }, plugin) : /* @__PURE__ */ jsx8("div", { ...pluginAttrs(plugin, styled), className, children: /* @__PURE__ */ jsx8(C, { ctx }) }, plugin)
|
|
1659
|
+
) });
|
|
1660
|
+
}
|
|
2951
1661
|
function TurnNotes({ turn }) {
|
|
2952
1662
|
const { strings: t } = usePiloto();
|
|
2953
1663
|
const failed = (turn.custom ?? []).filter((c) => c.name === "ghosty.attachments_failed").flatMap((c) => (c.value?.files ?? []).filter((f) => f?.name));
|
|
2954
1664
|
if (!failed.length && !turn.truncated) return null;
|
|
2955
|
-
return /* @__PURE__ */
|
|
2956
|
-
failed.map((f, i) => /* @__PURE__ */
|
|
2957
|
-
turn.truncated && /* @__PURE__ */
|
|
1665
|
+
return /* @__PURE__ */ jsxs6("div", { "data-turn-notes": true, className: "mt-1 flex flex-col gap-0.5 text-xs text-text-tertiary", children: [
|
|
1666
|
+
failed.map((f, i) => /* @__PURE__ */ jsx8("p", { children: t.attachmentFailed(f.name, f.reason) }, i)),
|
|
1667
|
+
turn.truncated && /* @__PURE__ */ jsx8("p", { children: turn.truncated.reason ?? t.truncated })
|
|
2958
1668
|
] });
|
|
2959
1669
|
}
|
|
2960
1670
|
|
|
2961
1671
|
// src/react/Subagents.tsx
|
|
2962
|
-
import { useState as
|
|
2963
|
-
import { jsx as
|
|
1672
|
+
import { useState as useState9 } from "react";
|
|
1673
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2964
1674
|
var DOT = {
|
|
2965
1675
|
running: "bg-brand-500 animate-pulse",
|
|
2966
1676
|
completed: "bg-text-tertiary",
|
|
@@ -2969,33 +1679,33 @@ var DOT = {
|
|
|
2969
1679
|
};
|
|
2970
1680
|
function Subagents({ pilot, defaultOpen = false, showFinished = true, className = "" }) {
|
|
2971
1681
|
const { strings: t } = usePiloto();
|
|
2972
|
-
const [open, setOpen] =
|
|
1682
|
+
const [open, setOpen] = useState9(defaultOpen);
|
|
2973
1683
|
const all = pilot.subagents;
|
|
2974
1684
|
const tasks = showFinished ? all : all.filter((x) => x.status === "running");
|
|
2975
1685
|
if (!tasks.length) return null;
|
|
2976
1686
|
const running = all.filter((x) => x.status === "running").length;
|
|
2977
|
-
return /* @__PURE__ */
|
|
2978
|
-
/* @__PURE__ */
|
|
2979
|
-
/* @__PURE__ */
|
|
2980
|
-
/* @__PURE__ */
|
|
2981
|
-
/* @__PURE__ */
|
|
1687
|
+
return /* @__PURE__ */ jsxs7("div", { "data-subagents": true, className: `mb-2 rounded-2xl border border-border-primary bg-background-secondary text-sm ${className}`, children: [
|
|
1688
|
+
/* @__PURE__ */ jsxs7("button", { type: "button", onClick: () => setOpen((o) => !o), "aria-expanded": open, className: "flex w-full items-center gap-2 px-3 py-2 text-left text-text-secondary", children: [
|
|
1689
|
+
/* @__PURE__ */ jsx9("span", { className: `h-2 w-2 shrink-0 rounded-full ${running ? DOT.running : DOT.completed}` }),
|
|
1690
|
+
/* @__PURE__ */ jsx9("span", { className: "flex-1 truncate", children: running ? t.subagentsWorking(running) : t.subagentsDone(tasks.length) }),
|
|
1691
|
+
/* @__PURE__ */ jsx9("span", { "aria-hidden": true, className: `text-text-tertiary transition-transform ${open ? "rotate-180" : ""}`, children: "\u2304" })
|
|
2982
1692
|
] }),
|
|
2983
|
-
open && /* @__PURE__ */
|
|
1693
|
+
open && /* @__PURE__ */ jsx9("ul", { className: "flex flex-col border-t border-border-primary", children: tasks.map((task) => /* @__PURE__ */ jsx9(SubagentRow, { task, onStop: () => void pilot.stopSubagent(task.id) }, task.id)) })
|
|
2984
1694
|
] });
|
|
2985
1695
|
}
|
|
2986
1696
|
function SubagentRow({ task, onStop }) {
|
|
2987
1697
|
const { strings: t } = usePiloto();
|
|
2988
1698
|
const line = task.status === "running" ? task.lastTool : task.summary ?? task.lastTool;
|
|
2989
|
-
return /* @__PURE__ */
|
|
2990
|
-
/* @__PURE__ */
|
|
2991
|
-
/* @__PURE__ */
|
|
2992
|
-
/* @__PURE__ */
|
|
2993
|
-
/* @__PURE__ */
|
|
1699
|
+
return /* @__PURE__ */ jsxs7("li", { "data-subagent": task.id, "data-status": task.status, className: "flex items-center gap-2 px-3 py-2", children: [
|
|
1700
|
+
/* @__PURE__ */ jsx9("span", { className: `h-2 w-2 shrink-0 rounded-full ${DOT[task.status] ?? DOT.completed}` }),
|
|
1701
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
1702
|
+
/* @__PURE__ */ jsx9("div", { className: "truncate text-text-primary", children: task.title ?? task.id }),
|
|
1703
|
+
/* @__PURE__ */ jsxs7("div", { className: "truncate text-xs text-text-tertiary", children: [
|
|
2994
1704
|
t.subagentStatus[task.status] ?? task.status,
|
|
2995
1705
|
line ? ` \xB7 ${line}` : ""
|
|
2996
1706
|
] })
|
|
2997
1707
|
] }),
|
|
2998
|
-
task.status === "running" && /* @__PURE__ */
|
|
1708
|
+
task.status === "running" && /* @__PURE__ */ jsx9("button", { type: "button", onClick: onStop, className: "shrink-0 rounded-full border border-border-primary px-2.5 py-0.5 text-xs text-text-secondary transition hover:text-text-danger", children: t.subagentStop })
|
|
2999
1709
|
] });
|
|
3000
1710
|
}
|
|
3001
1711
|
export {
|
|
@@ -3041,8 +1751,10 @@ export {
|
|
|
3041
1751
|
createAgUiTransport,
|
|
3042
1752
|
createPilotState,
|
|
3043
1753
|
Piloto as default,
|
|
1754
|
+
definePlugin,
|
|
3044
1755
|
dropLastExchange,
|
|
3045
1756
|
expiryMs,
|
|
1757
|
+
extractBlocks,
|
|
3046
1758
|
extractReplyOptions,
|
|
3047
1759
|
formatDuration,
|
|
3048
1760
|
groupSteps,
|
|
@@ -3053,12 +1765,15 @@ export {
|
|
|
3053
1765
|
messagesToTurns,
|
|
3054
1766
|
mimeOf,
|
|
3055
1767
|
narrationToMarkdown,
|
|
1768
|
+
pluginPoints,
|
|
1769
|
+
pluginRequires,
|
|
3056
1770
|
prependHistory,
|
|
3057
1771
|
queueMessage,
|
|
3058
1772
|
readSse,
|
|
3059
1773
|
reduceAgUiEvent,
|
|
3060
1774
|
renderInline,
|
|
3061
1775
|
resolvePermission,
|
|
1776
|
+
resolvePlugins,
|
|
3062
1777
|
sendFailed,
|
|
3063
1778
|
splitNarration,
|
|
3064
1779
|
stepLabel,
|