@tangle-network/sandbox-ui 0.57.0 → 0.59.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/dist/chat.d.ts +134 -36
- package/dist/chat.js +5 -3
- package/dist/{chunk-NHHYPID3.js → chunk-4XOZGMJC.js} +487 -131
- package/dist/{chunk-SVNWL3ZR.js → chunk-D7JJLG4L.js} +1 -1
- package/dist/{chunk-DLKDWMFM.js → chunk-MKX3F55O.js} +1 -1
- package/dist/dashboard.js +1 -1
- package/dist/globals.css +43 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +7 -5
- package/dist/styles.css +43 -0
- package/dist/workbench.js +2 -2
- package/package.json +3 -3
|
@@ -146,78 +146,308 @@ function ReasoningLevelPicker({
|
|
|
146
146
|
// src/chat/agent-session-controls.tsx
|
|
147
147
|
import { reasoningEffortsFor } from "@tangle-network/agent-interface";
|
|
148
148
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
149
|
-
import { ChevronDown as
|
|
149
|
+
import { ChevronDown as ChevronDown3, Lock, SlidersHorizontal } from "lucide-react";
|
|
150
150
|
|
|
151
151
|
// src/chat/harness-model-compat.ts
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
/^anthropic\/claude-opus-[\d.-]+$/,
|
|
158
|
-
/^anthropic\/claude-sonnet-[\d.-]+$/,
|
|
159
|
-
/^anthropic\//
|
|
160
|
-
]
|
|
161
|
-
},
|
|
162
|
-
codex: {
|
|
163
|
-
providers: ["openai"],
|
|
164
|
-
// Standard frontier tier first (gpt-N / gpt-N.N), then any gpt
|
|
165
|
-
// variant (mini/nano), then anything OpenAI.
|
|
166
|
-
preferred: [/^openai\/gpt-\d+(\.\d+)?$/, /^openai\/gpt/, /^openai\//]
|
|
167
|
-
},
|
|
168
|
-
amp: { providers: null, preferred: [] },
|
|
169
|
-
"factory-droids": { providers: null, preferred: [] },
|
|
170
|
-
"cli-base": { providers: null, preferred: [] },
|
|
171
|
-
"kimi-code": {
|
|
172
|
-
providers: ["moonshot"],
|
|
173
|
-
preferred: [/^moonshot\//]
|
|
174
|
-
},
|
|
175
|
-
openclaw: { providers: null, preferred: [] },
|
|
176
|
-
nanoclaw: { providers: null, preferred: [] },
|
|
177
|
-
hermes: { providers: null, preferred: [] }
|
|
178
|
-
};
|
|
179
|
-
var PROVIDER_PREFERRED_HARNESS = {
|
|
180
|
-
anthropic: "claude-code",
|
|
181
|
-
openai: "codex",
|
|
182
|
-
moonshot: "kimi-code"
|
|
183
|
-
};
|
|
184
|
-
function modelProvider(modelId) {
|
|
185
|
-
const slash = modelId.indexOf("/");
|
|
186
|
-
return slash > 0 ? modelId.slice(0, slash) : null;
|
|
187
|
-
}
|
|
152
|
+
import {
|
|
153
|
+
harnessSupportsModel,
|
|
154
|
+
snapModelToHarness as snapModelIdToHarness
|
|
155
|
+
} from "@tangle-network/agent-interface";
|
|
156
|
+
import { modelProvider, snapHarnessToModel } from "@tangle-network/agent-interface";
|
|
188
157
|
function isModelCompatibleWithHarness(harness, modelId) {
|
|
189
|
-
|
|
190
|
-
if (!policy || policy.providers === null) return true;
|
|
191
|
-
const provider = modelProvider(modelId);
|
|
192
|
-
if (!provider) return true;
|
|
193
|
-
return policy.providers.includes(provider);
|
|
158
|
+
return harnessSupportsModel(harness, modelId);
|
|
194
159
|
}
|
|
195
|
-
var numericDesc = new Intl.Collator(void 0, {
|
|
196
|
-
numeric: true,
|
|
197
|
-
sensitivity: "base"
|
|
198
|
-
});
|
|
199
160
|
function snapModelToHarness(harness, modelId, models) {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
161
|
+
return snapModelIdToHarness(harness, modelId, models.map(canonicalModelId));
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// src/chat/agent-profile-picker.tsx
|
|
165
|
+
import { Bot, Check, ChevronDown as ChevronDown2, Pencil, Plus, Trash2 } from "lucide-react";
|
|
166
|
+
import * as React from "react";
|
|
167
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
168
|
+
function useClickOutside(onOutside) {
|
|
169
|
+
const ref = React.useRef(null);
|
|
170
|
+
React.useEffect(() => {
|
|
171
|
+
function handler(event) {
|
|
172
|
+
if (ref.current && !ref.current.contains(event.target)) {
|
|
173
|
+
onOutside();
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
document.addEventListener("mousedown", handler);
|
|
177
|
+
return () => document.removeEventListener("mousedown", handler);
|
|
178
|
+
}, [onOutside]);
|
|
179
|
+
return ref;
|
|
180
|
+
}
|
|
181
|
+
function profileSubtitle(profile) {
|
|
182
|
+
if (profile.description) return profile.description;
|
|
183
|
+
const count = profile.capabilities?.length ?? 0;
|
|
184
|
+
return `${count} ${count === 1 ? "tool group" : "tool groups"}`;
|
|
185
|
+
}
|
|
186
|
+
function AgentProfilePicker({
|
|
187
|
+
value,
|
|
188
|
+
onChange,
|
|
189
|
+
profiles,
|
|
190
|
+
capabilities,
|
|
191
|
+
onCreate,
|
|
192
|
+
onUpdate,
|
|
193
|
+
onDelete,
|
|
194
|
+
disabled,
|
|
195
|
+
className,
|
|
196
|
+
side = "top"
|
|
197
|
+
}) {
|
|
198
|
+
const [open, setOpen] = React.useState(false);
|
|
199
|
+
const [composing, setComposing] = React.useState(
|
|
200
|
+
null
|
|
201
|
+
);
|
|
202
|
+
const ref = useClickOutside(() => {
|
|
203
|
+
setOpen(false);
|
|
204
|
+
setComposing(null);
|
|
205
|
+
});
|
|
206
|
+
const canAuthor = Boolean(capabilities && (onCreate || onUpdate));
|
|
207
|
+
const builtins = profiles.filter((profile) => profile.builtin);
|
|
208
|
+
const custom = profiles.filter((profile) => !profile.builtin);
|
|
209
|
+
const selected = profiles.find((profile) => profile.id === value);
|
|
210
|
+
function select(id) {
|
|
211
|
+
onChange(id);
|
|
212
|
+
setOpen(false);
|
|
213
|
+
}
|
|
214
|
+
async function save(draft) {
|
|
215
|
+
if (draft.id) await onUpdate?.(draft.id, draft);
|
|
216
|
+
else await onCreate?.(draft);
|
|
217
|
+
setComposing(null);
|
|
207
218
|
}
|
|
208
|
-
|
|
209
|
-
|
|
219
|
+
return /* @__PURE__ */ jsxs2("div", { ref, className: cn("relative inline-flex", className), children: [
|
|
220
|
+
/* @__PURE__ */ jsxs2(
|
|
221
|
+
"button",
|
|
222
|
+
{
|
|
223
|
+
type: "button",
|
|
224
|
+
disabled,
|
|
225
|
+
onClick: () => setOpen((v) => !v),
|
|
226
|
+
className: cn(
|
|
227
|
+
"inline-flex h-8 items-center gap-1.5 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-2.5",
|
|
228
|
+
"text-xs font-medium text-foreground shadow-sm transition-colors",
|
|
229
|
+
"hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
230
|
+
"data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high",
|
|
231
|
+
"disabled:cursor-not-allowed disabled:opacity-60"
|
|
232
|
+
),
|
|
233
|
+
"data-state": open ? "open" : "closed",
|
|
234
|
+
"aria-label": "Agent profile",
|
|
235
|
+
children: [
|
|
236
|
+
/* @__PURE__ */ jsx2(Bot, { className: "h-3.5 w-3.5 text-muted-foreground" }),
|
|
237
|
+
/* @__PURE__ */ jsx2("span", { className: "max-w-[140px] truncate", children: selected?.name ?? value }),
|
|
238
|
+
/* @__PURE__ */ jsx2(ChevronDown2, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
239
|
+
]
|
|
240
|
+
}
|
|
241
|
+
),
|
|
242
|
+
open && /* @__PURE__ */ jsx2(
|
|
243
|
+
"div",
|
|
244
|
+
{
|
|
245
|
+
className: cn(
|
|
246
|
+
"absolute left-0 z-50 w-[320px] overflow-hidden rounded-[var(--radius-md)] border border-[var(--md3-outline-variant)] bg-surface-container-highest p-1",
|
|
247
|
+
"shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]",
|
|
248
|
+
side === "top" ? "bottom-full mb-2" : "top-full mt-2"
|
|
249
|
+
),
|
|
250
|
+
children: composing ? /* @__PURE__ */ jsx2(
|
|
251
|
+
ProfileForm,
|
|
252
|
+
{
|
|
253
|
+
capabilities: capabilities ?? [],
|
|
254
|
+
initial: composing === "new" ? void 0 : composing,
|
|
255
|
+
onCancel: () => setComposing(null),
|
|
256
|
+
onSave: save
|
|
257
|
+
}
|
|
258
|
+
) : /* @__PURE__ */ jsxs2("div", { className: "max-h-[min(60vh,420px)] overflow-y-auto", children: [
|
|
259
|
+
/* @__PURE__ */ jsx2(SectionHeader, { children: "Modes" }),
|
|
260
|
+
builtins.map((profile) => /* @__PURE__ */ jsx2(
|
|
261
|
+
ProfileRow,
|
|
262
|
+
{
|
|
263
|
+
active: profile.id === value,
|
|
264
|
+
title: profile.name,
|
|
265
|
+
subtitle: profileSubtitle(profile),
|
|
266
|
+
onSelect: () => select(profile.id)
|
|
267
|
+
},
|
|
268
|
+
profile.id
|
|
269
|
+
)),
|
|
270
|
+
custom.length > 0 && /* @__PURE__ */ jsx2(SectionHeader, { children: "Your agents" }),
|
|
271
|
+
custom.map((profile) => /* @__PURE__ */ jsx2(
|
|
272
|
+
ProfileRow,
|
|
273
|
+
{
|
|
274
|
+
active: profile.id === value,
|
|
275
|
+
title: profile.name,
|
|
276
|
+
subtitle: profileSubtitle(profile),
|
|
277
|
+
onSelect: () => select(profile.id),
|
|
278
|
+
onEdit: canAuthor ? () => setComposing(profile) : void 0,
|
|
279
|
+
onDelete: onDelete ? () => void onDelete(profile.id) : void 0
|
|
280
|
+
},
|
|
281
|
+
profile.id
|
|
282
|
+
)),
|
|
283
|
+
canAuthor && /* @__PURE__ */ jsxs2(
|
|
284
|
+
"button",
|
|
285
|
+
{
|
|
286
|
+
type: "button",
|
|
287
|
+
onClick: () => setComposing("new"),
|
|
288
|
+
className: "mt-1 flex w-full items-center gap-2 rounded-md px-2.5 py-2 text-left text-sm text-[var(--accent-text)] transition-colors hover:bg-accent/40",
|
|
289
|
+
children: [
|
|
290
|
+
/* @__PURE__ */ jsx2(Plus, { className: "h-4 w-4" }),
|
|
291
|
+
" New agent\u2026"
|
|
292
|
+
]
|
|
293
|
+
}
|
|
294
|
+
)
|
|
295
|
+
] })
|
|
296
|
+
}
|
|
297
|
+
)
|
|
298
|
+
] });
|
|
299
|
+
}
|
|
300
|
+
function SectionHeader({ children }) {
|
|
301
|
+
return /* @__PURE__ */ jsx2("div", { className: "px-2.5 pb-1 pt-2 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children });
|
|
302
|
+
}
|
|
303
|
+
function ProfileRow({
|
|
304
|
+
active,
|
|
305
|
+
title,
|
|
306
|
+
subtitle,
|
|
307
|
+
onSelect,
|
|
308
|
+
onEdit,
|
|
309
|
+
onDelete
|
|
310
|
+
}) {
|
|
311
|
+
return /* @__PURE__ */ jsxs2(
|
|
312
|
+
"div",
|
|
313
|
+
{
|
|
314
|
+
className: cn(
|
|
315
|
+
"group flex items-center gap-2 rounded-md px-2.5 py-2 text-sm transition-colors",
|
|
316
|
+
active ? "bg-[var(--accent-surface-soft)] text-[var(--accent-text)]" : "hover:bg-accent/40"
|
|
317
|
+
),
|
|
318
|
+
children: [
|
|
319
|
+
/* @__PURE__ */ jsxs2(
|
|
320
|
+
"button",
|
|
321
|
+
{
|
|
322
|
+
type: "button",
|
|
323
|
+
onClick: onSelect,
|
|
324
|
+
className: "flex min-w-0 flex-1 items-center gap-2 text-left",
|
|
325
|
+
children: [
|
|
326
|
+
/* @__PURE__ */ jsx2("span", { className: "flex h-4 w-4 shrink-0 items-center justify-center", children: active && /* @__PURE__ */ jsx2(Check, { className: "h-3.5 w-3.5" }) }),
|
|
327
|
+
/* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
|
|
328
|
+
/* @__PURE__ */ jsx2("span", { className: "block truncate font-medium", children: title }),
|
|
329
|
+
/* @__PURE__ */ jsx2("span", { className: "block truncate text-xs text-muted-foreground", children: subtitle })
|
|
330
|
+
] })
|
|
331
|
+
]
|
|
332
|
+
}
|
|
333
|
+
),
|
|
334
|
+
(onEdit || onDelete) && /* @__PURE__ */ jsxs2("span", { className: "flex shrink-0 items-center gap-1 opacity-0 transition-opacity group-hover:opacity-100", children: [
|
|
335
|
+
onEdit && /* @__PURE__ */ jsx2(
|
|
336
|
+
"button",
|
|
337
|
+
{
|
|
338
|
+
type: "button",
|
|
339
|
+
onClick: onEdit,
|
|
340
|
+
title: "Edit",
|
|
341
|
+
className: "rounded p-1 text-muted-foreground hover:text-foreground",
|
|
342
|
+
children: /* @__PURE__ */ jsx2(Pencil, { className: "h-3 w-3" })
|
|
343
|
+
}
|
|
344
|
+
),
|
|
345
|
+
onDelete && /* @__PURE__ */ jsx2(
|
|
346
|
+
"button",
|
|
347
|
+
{
|
|
348
|
+
type: "button",
|
|
349
|
+
onClick: onDelete,
|
|
350
|
+
title: "Delete",
|
|
351
|
+
className: "rounded p-1 text-muted-foreground hover:text-[var(--status-error,#ff4d6d)]",
|
|
352
|
+
children: /* @__PURE__ */ jsx2(Trash2, { className: "h-3 w-3" })
|
|
353
|
+
}
|
|
354
|
+
)
|
|
355
|
+
] })
|
|
356
|
+
]
|
|
357
|
+
}
|
|
210
358
|
);
|
|
211
|
-
return fallback ?? modelId;
|
|
212
359
|
}
|
|
213
|
-
function
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
360
|
+
function ProfileForm({
|
|
361
|
+
capabilities,
|
|
362
|
+
initial,
|
|
363
|
+
onCancel,
|
|
364
|
+
onSave
|
|
365
|
+
}) {
|
|
366
|
+
const [name, setName] = React.useState(initial?.name ?? "");
|
|
367
|
+
const [caps, setCaps] = React.useState(
|
|
368
|
+
initial?.capabilities ? [...initial.capabilities] : capabilities.map((c) => c.id)
|
|
369
|
+
);
|
|
370
|
+
const [instructions, setInstructions] = React.useState(initial?.instructions ?? "");
|
|
371
|
+
const toggle = (id) => setCaps(
|
|
372
|
+
(prev) => prev.includes(id) ? prev.filter((c) => c !== id) : [...prev, id]
|
|
373
|
+
);
|
|
374
|
+
return /* @__PURE__ */ jsxs2("div", { className: "space-y-3 p-2.5", children: [
|
|
375
|
+
/* @__PURE__ */ jsx2(
|
|
376
|
+
"input",
|
|
377
|
+
{
|
|
378
|
+
autoFocus: true,
|
|
379
|
+
value: name,
|
|
380
|
+
onChange: (event) => setName(event.target.value),
|
|
381
|
+
placeholder: "Agent name (e.g. Tax Reviewer)",
|
|
382
|
+
className: "w-full rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-3 py-2 text-sm outline-none focus:border-primary"
|
|
383
|
+
}
|
|
384
|
+
),
|
|
385
|
+
capabilities.length > 0 && /* @__PURE__ */ jsxs2("div", { children: [
|
|
386
|
+
/* @__PURE__ */ jsx2("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wide text-muted-foreground/70", children: "Tools" }),
|
|
387
|
+
/* @__PURE__ */ jsx2("div", { className: "space-y-0.5", children: capabilities.map((cap) => /* @__PURE__ */ jsxs2(
|
|
388
|
+
"label",
|
|
389
|
+
{
|
|
390
|
+
className: "flex cursor-pointer items-start gap-2 rounded-md px-2 py-1.5 hover:bg-accent/40",
|
|
391
|
+
children: [
|
|
392
|
+
/* @__PURE__ */ jsx2(
|
|
393
|
+
"input",
|
|
394
|
+
{
|
|
395
|
+
type: "checkbox",
|
|
396
|
+
checked: caps.includes(cap.id),
|
|
397
|
+
onChange: () => toggle(cap.id),
|
|
398
|
+
className: "mt-0.5"
|
|
399
|
+
}
|
|
400
|
+
),
|
|
401
|
+
/* @__PURE__ */ jsxs2("span", { className: "min-w-0", children: [
|
|
402
|
+
/* @__PURE__ */ jsx2("span", { className: "block text-sm font-medium", children: cap.label }),
|
|
403
|
+
cap.description && /* @__PURE__ */ jsx2("span", { className: "block text-xs text-muted-foreground", children: cap.description })
|
|
404
|
+
] })
|
|
405
|
+
]
|
|
406
|
+
},
|
|
407
|
+
cap.id
|
|
408
|
+
)) })
|
|
409
|
+
] }),
|
|
410
|
+
/* @__PURE__ */ jsx2(
|
|
411
|
+
"textarea",
|
|
412
|
+
{
|
|
413
|
+
value: instructions,
|
|
414
|
+
onChange: (event) => setInstructions(event.target.value),
|
|
415
|
+
rows: 2,
|
|
416
|
+
placeholder: "Instructions (optional) \u2014 how this agent should behave",
|
|
417
|
+
className: "w-full resize-none rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-3 py-2 text-sm outline-none focus:border-primary"
|
|
418
|
+
}
|
|
419
|
+
),
|
|
420
|
+
/* @__PURE__ */ jsxs2("div", { className: "flex justify-end gap-2", children: [
|
|
421
|
+
/* @__PURE__ */ jsx2(
|
|
422
|
+
"button",
|
|
423
|
+
{
|
|
424
|
+
type: "button",
|
|
425
|
+
onClick: onCancel,
|
|
426
|
+
className: "rounded-lg px-3 py-1.5 text-sm text-muted-foreground hover:bg-accent/40",
|
|
427
|
+
children: "Cancel"
|
|
428
|
+
}
|
|
429
|
+
),
|
|
430
|
+
/* @__PURE__ */ jsx2(
|
|
431
|
+
"button",
|
|
432
|
+
{
|
|
433
|
+
type: "button",
|
|
434
|
+
disabled: !name.trim(),
|
|
435
|
+
onClick: () => onSave({
|
|
436
|
+
id: initial?.id,
|
|
437
|
+
name: name.trim(),
|
|
438
|
+
capabilities: caps,
|
|
439
|
+
instructions: instructions.trim()
|
|
440
|
+
}),
|
|
441
|
+
className: "rounded-lg bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground transition-opacity hover:opacity-90 disabled:opacity-40",
|
|
442
|
+
children: "Save agent"
|
|
443
|
+
}
|
|
444
|
+
)
|
|
445
|
+
] })
|
|
446
|
+
] });
|
|
217
447
|
}
|
|
218
448
|
|
|
219
449
|
// src/chat/agent-session-controls.tsx
|
|
220
|
-
import { jsx as
|
|
450
|
+
import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
221
451
|
function HarnessDropdown({
|
|
222
452
|
value,
|
|
223
453
|
onChange,
|
|
@@ -234,8 +464,8 @@ function HarnessDropdown({
|
|
|
234
464
|
);
|
|
235
465
|
const options = HARNESS_OPTIONS.filter((h) => allowed.has(h.type));
|
|
236
466
|
const selected = options.find((option) => option.type === value);
|
|
237
|
-
return /* @__PURE__ */
|
|
238
|
-
/* @__PURE__ */
|
|
467
|
+
return /* @__PURE__ */ jsxs3(DropdownMenu2.Root, { children: [
|
|
468
|
+
/* @__PURE__ */ jsx3(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
|
|
239
469
|
"button",
|
|
240
470
|
{
|
|
241
471
|
type: "button",
|
|
@@ -250,13 +480,13 @@ function HarnessDropdown({
|
|
|
250
480
|
),
|
|
251
481
|
"aria-label": "Agent harness",
|
|
252
482
|
children: [
|
|
253
|
-
locked ? /* @__PURE__ */
|
|
254
|
-
/* @__PURE__ */
|
|
255
|
-
!locked && /* @__PURE__ */
|
|
483
|
+
locked ? /* @__PURE__ */ jsx3(Lock, { className: "h-3 w-3 text-muted-foreground" }) : /* @__PURE__ */ jsx3(HarnessLogo, { type: value, size: 16 }),
|
|
484
|
+
/* @__PURE__ */ jsx3("span", { children: selected?.label ?? value }),
|
|
485
|
+
!locked && /* @__PURE__ */ jsx3(ChevronDown3, { className: "h-3.5 w-3.5 text-muted-foreground" })
|
|
256
486
|
]
|
|
257
487
|
}
|
|
258
488
|
) }),
|
|
259
|
-
/* @__PURE__ */
|
|
489
|
+
/* @__PURE__ */ jsx3(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsx3(
|
|
260
490
|
DropdownMenu2.Content,
|
|
261
491
|
{
|
|
262
492
|
side,
|
|
@@ -274,7 +504,7 @@ function HarnessDropdown({
|
|
|
274
504
|
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
|
|
275
505
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
|
276
506
|
),
|
|
277
|
-
children: options.map((option) => /* @__PURE__ */
|
|
507
|
+
children: options.map((option) => /* @__PURE__ */ jsxs3(
|
|
278
508
|
DropdownMenu2.Item,
|
|
279
509
|
{
|
|
280
510
|
onSelect: (event) => {
|
|
@@ -287,10 +517,10 @@ function HarnessDropdown({
|
|
|
287
517
|
option.type === value && "bg-primary/10 font-medium text-foreground ring-1 ring-inset ring-primary/25 hover:bg-primary/15 focus:bg-primary/15"
|
|
288
518
|
),
|
|
289
519
|
children: [
|
|
290
|
-
/* @__PURE__ */
|
|
291
|
-
/* @__PURE__ */
|
|
292
|
-
/* @__PURE__ */
|
|
293
|
-
option.description && /* @__PURE__ */
|
|
520
|
+
/* @__PURE__ */ jsx3(HarnessLogo, { type: option.type, size: 20, className: "mt-0.5" }),
|
|
521
|
+
/* @__PURE__ */ jsxs3("span", { className: "flex min-w-0 flex-col gap-0.5", children: [
|
|
522
|
+
/* @__PURE__ */ jsx3("span", { className: "text-sm font-medium", children: option.label }),
|
|
523
|
+
option.description && /* @__PURE__ */ jsx3("span", { className: "text-xs text-muted-foreground", children: option.description })
|
|
294
524
|
] })
|
|
295
525
|
]
|
|
296
526
|
},
|
|
@@ -302,6 +532,7 @@ function HarnessDropdown({
|
|
|
302
532
|
}
|
|
303
533
|
function AgentSessionControls({
|
|
304
534
|
harness,
|
|
535
|
+
profile,
|
|
305
536
|
model,
|
|
306
537
|
reasoning,
|
|
307
538
|
trailing,
|
|
@@ -310,7 +541,7 @@ function AgentSessionControls({
|
|
|
310
541
|
layout = "inline",
|
|
311
542
|
menuPlacement = "auto"
|
|
312
543
|
}) {
|
|
313
|
-
if (!harness && !model && !reasoning && !trailing) return null;
|
|
544
|
+
if (!harness && !profile && !model && !reasoning && !trailing) return null;
|
|
314
545
|
const handleHarnessChange = (next) => {
|
|
315
546
|
harness?.onChange(next);
|
|
316
547
|
if (model) {
|
|
@@ -336,7 +567,7 @@ function AgentSessionControls({
|
|
|
336
567
|
const menuAlign = layout === "gear" ? "end" : "start";
|
|
337
568
|
const inlineForceDown = menuPlacement === "down" && layout !== "gear";
|
|
338
569
|
const avoidCollisions = inlineForceDown ? false : void 0;
|
|
339
|
-
const harnessNode = harness && /* @__PURE__ */
|
|
570
|
+
const harnessNode = harness && /* @__PURE__ */ jsx3(
|
|
340
571
|
HarnessDropdown,
|
|
341
572
|
{
|
|
342
573
|
...harness,
|
|
@@ -347,7 +578,21 @@ function AgentSessionControls({
|
|
|
347
578
|
avoidCollisions
|
|
348
579
|
}
|
|
349
580
|
);
|
|
350
|
-
const
|
|
581
|
+
const profileNode = profile && /* @__PURE__ */ jsx3(
|
|
582
|
+
AgentProfilePicker,
|
|
583
|
+
{
|
|
584
|
+
value: profile.value,
|
|
585
|
+
onChange: profile.onChange,
|
|
586
|
+
profiles: profile.profiles,
|
|
587
|
+
capabilities: profile.capabilities,
|
|
588
|
+
onCreate: profile.onCreate,
|
|
589
|
+
onUpdate: profile.onUpdate,
|
|
590
|
+
onDelete: profile.onDelete,
|
|
591
|
+
disabled: profile.disabled,
|
|
592
|
+
side: inlineForceDown || layout === "gear" ? "bottom" : "top"
|
|
593
|
+
}
|
|
594
|
+
);
|
|
595
|
+
const modelNode = model && /* @__PURE__ */ jsx3(
|
|
351
596
|
ModelPicker,
|
|
352
597
|
{
|
|
353
598
|
variant: "pill",
|
|
@@ -370,7 +615,7 @@ function AgentSessionControls({
|
|
|
370
615
|
supportsReasoning: selectedModel.supportsReasoning,
|
|
371
616
|
maxEffort: selectedModel.maxReasoningEffort
|
|
372
617
|
} : null;
|
|
373
|
-
const reasoningNode = reasoning && /* @__PURE__ */
|
|
618
|
+
const reasoningNode = reasoning && /* @__PURE__ */ jsx3(
|
|
374
619
|
ReasoningLevelPicker,
|
|
375
620
|
{
|
|
376
621
|
value: reasoning.value,
|
|
@@ -383,10 +628,11 @@ function AgentSessionControls({
|
|
|
383
628
|
}
|
|
384
629
|
);
|
|
385
630
|
if (layout === "gear") {
|
|
386
|
-
return /* @__PURE__ */
|
|
631
|
+
return /* @__PURE__ */ jsx3(
|
|
387
632
|
GearControls,
|
|
388
633
|
{
|
|
389
634
|
className,
|
|
635
|
+
profileNode,
|
|
390
636
|
harnessNode,
|
|
391
637
|
modelNode,
|
|
392
638
|
reasoningNode,
|
|
@@ -394,36 +640,38 @@ function AgentSessionControls({
|
|
|
394
640
|
}
|
|
395
641
|
);
|
|
396
642
|
}
|
|
397
|
-
return /* @__PURE__ */
|
|
643
|
+
return /* @__PURE__ */ jsxs3(
|
|
398
644
|
"div",
|
|
399
645
|
{
|
|
400
646
|
className: cn("flex flex-wrap items-center gap-2", className),
|
|
401
647
|
"data-testid": "agent-session-controls",
|
|
402
648
|
children: [
|
|
649
|
+
profileNode,
|
|
403
650
|
harnessNode,
|
|
404
651
|
modelNode,
|
|
405
652
|
reasoningNode,
|
|
406
|
-
trailing && /* @__PURE__ */
|
|
653
|
+
trailing && /* @__PURE__ */ jsx3("div", { className: "ml-auto flex items-center gap-2", children: trailing })
|
|
407
654
|
]
|
|
408
655
|
}
|
|
409
656
|
);
|
|
410
657
|
}
|
|
411
658
|
function GearControls({
|
|
412
659
|
className,
|
|
660
|
+
profileNode,
|
|
413
661
|
harnessNode,
|
|
414
662
|
modelNode,
|
|
415
663
|
reasoningNode,
|
|
416
664
|
trailing
|
|
417
665
|
}) {
|
|
418
|
-
return /* @__PURE__ */
|
|
666
|
+
return /* @__PURE__ */ jsxs3(
|
|
419
667
|
"div",
|
|
420
668
|
{
|
|
421
669
|
className: cn("flex items-center gap-2", className),
|
|
422
670
|
"data-testid": "agent-session-controls",
|
|
423
671
|
children: [
|
|
424
|
-
trailing && /* @__PURE__ */
|
|
425
|
-
/* @__PURE__ */
|
|
426
|
-
/* @__PURE__ */
|
|
672
|
+
trailing && /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-2", children: trailing }),
|
|
673
|
+
/* @__PURE__ */ jsxs3(DropdownMenu2.Root, { children: [
|
|
674
|
+
/* @__PURE__ */ jsx3(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx3(
|
|
427
675
|
"button",
|
|
428
676
|
{
|
|
429
677
|
type: "button",
|
|
@@ -434,10 +682,10 @@ function GearControls({
|
|
|
434
682
|
"hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
435
683
|
"data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high"
|
|
436
684
|
),
|
|
437
|
-
children: /* @__PURE__ */
|
|
685
|
+
children: /* @__PURE__ */ jsx3(SlidersHorizontal, { className: "h-4 w-4 text-muted-foreground" })
|
|
438
686
|
}
|
|
439
687
|
) }),
|
|
440
|
-
/* @__PURE__ */
|
|
688
|
+
/* @__PURE__ */ jsx3(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs3(
|
|
441
689
|
DropdownMenu2.Content,
|
|
442
690
|
{
|
|
443
691
|
side: "top",
|
|
@@ -459,9 +707,10 @@ function GearControls({
|
|
|
459
707
|
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
|
|
460
708
|
),
|
|
461
709
|
children: [
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
710
|
+
profileNode && /* @__PURE__ */ jsx3(GearSection, { label: "Agent", children: profileNode }),
|
|
711
|
+
harnessNode && /* @__PURE__ */ jsx3(GearSection, { label: "Harness", children: harnessNode }),
|
|
712
|
+
modelNode && /* @__PURE__ */ jsx3(GearSection, { label: "Model", children: modelNode }),
|
|
713
|
+
reasoningNode && /* @__PURE__ */ jsx3(GearSection, { label: "Effort", children: reasoningNode })
|
|
465
714
|
]
|
|
466
715
|
}
|
|
467
716
|
) })
|
|
@@ -474,17 +723,123 @@ function GearSection({
|
|
|
474
723
|
label,
|
|
475
724
|
children
|
|
476
725
|
}) {
|
|
477
|
-
return /* @__PURE__ */
|
|
478
|
-
/* @__PURE__ */
|
|
726
|
+
return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
|
|
727
|
+
/* @__PURE__ */ jsx3("span", { className: "px-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70", children: label }),
|
|
479
728
|
children
|
|
480
729
|
] });
|
|
481
730
|
}
|
|
482
731
|
|
|
732
|
+
// src/chat/agent-composer.tsx
|
|
733
|
+
import { ArrowUp, Loader2 } from "lucide-react";
|
|
734
|
+
import * as React2 from "react";
|
|
735
|
+
import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
736
|
+
function AgentComposer({
|
|
737
|
+
value,
|
|
738
|
+
onChange,
|
|
739
|
+
onSubmit,
|
|
740
|
+
placeholder = "Send a message\u2026",
|
|
741
|
+
disabled,
|
|
742
|
+
busy,
|
|
743
|
+
harness,
|
|
744
|
+
profile,
|
|
745
|
+
model,
|
|
746
|
+
reasoning,
|
|
747
|
+
context = "chat",
|
|
748
|
+
trailing,
|
|
749
|
+
minRows = 2,
|
|
750
|
+
maxHeight = 200,
|
|
751
|
+
className,
|
|
752
|
+
sendLabel = "Send",
|
|
753
|
+
autoFocus
|
|
754
|
+
}) {
|
|
755
|
+
const textareaRef = React2.useRef(null);
|
|
756
|
+
const resize = React2.useCallback(
|
|
757
|
+
(el) => {
|
|
758
|
+
el.style.height = "auto";
|
|
759
|
+
el.style.height = `${Math.min(el.scrollHeight, maxHeight)}px`;
|
|
760
|
+
},
|
|
761
|
+
[maxHeight]
|
|
762
|
+
);
|
|
763
|
+
React2.useEffect(() => {
|
|
764
|
+
if (textareaRef.current) resize(textareaRef.current);
|
|
765
|
+
}, [value, resize]);
|
|
766
|
+
const canSend = !disabled && !busy && value.trim().length > 0;
|
|
767
|
+
const submit = () => {
|
|
768
|
+
if (!canSend) return;
|
|
769
|
+
onSubmit();
|
|
770
|
+
};
|
|
771
|
+
return /* @__PURE__ */ jsxs4(
|
|
772
|
+
"div",
|
|
773
|
+
{
|
|
774
|
+
"data-testid": "agent-composer",
|
|
775
|
+
className: cn(
|
|
776
|
+
"flex flex-col gap-2 rounded-2xl border border-[var(--md3-outline-variant)] bg-surface-container-high p-2.5 shadow-sm transition-colors",
|
|
777
|
+
"focus-within:border-primary/60",
|
|
778
|
+
disabled && "opacity-60",
|
|
779
|
+
className
|
|
780
|
+
),
|
|
781
|
+
children: [
|
|
782
|
+
/* @__PURE__ */ jsx4(
|
|
783
|
+
"textarea",
|
|
784
|
+
{
|
|
785
|
+
ref: textareaRef,
|
|
786
|
+
rows: minRows,
|
|
787
|
+
value,
|
|
788
|
+
disabled,
|
|
789
|
+
autoFocus,
|
|
790
|
+
onChange: (event) => onChange(event.target.value),
|
|
791
|
+
onInput: (event) => resize(event.currentTarget),
|
|
792
|
+
onKeyDown: (event) => {
|
|
793
|
+
if (event.key === "Enter" && !event.shiftKey && !event.nativeEvent.isComposing && event.keyCode !== 229) {
|
|
794
|
+
event.preventDefault();
|
|
795
|
+
submit();
|
|
796
|
+
}
|
|
797
|
+
},
|
|
798
|
+
placeholder,
|
|
799
|
+
className: cn(
|
|
800
|
+
"w-full resize-none bg-transparent px-2 py-1 text-sm leading-relaxed text-foreground outline-none",
|
|
801
|
+
"placeholder:text-muted-foreground"
|
|
802
|
+
)
|
|
803
|
+
}
|
|
804
|
+
),
|
|
805
|
+
/* @__PURE__ */ jsxs4("div", { className: "flex items-end gap-2", children: [
|
|
806
|
+
/* @__PURE__ */ jsx4(
|
|
807
|
+
AgentSessionControls,
|
|
808
|
+
{
|
|
809
|
+
className: "min-w-0 flex-1",
|
|
810
|
+
context,
|
|
811
|
+
harness,
|
|
812
|
+
profile,
|
|
813
|
+
model,
|
|
814
|
+
reasoning
|
|
815
|
+
}
|
|
816
|
+
),
|
|
817
|
+
trailing && /* @__PURE__ */ jsx4("div", { className: "flex shrink-0 items-center gap-2", children: trailing }),
|
|
818
|
+
/* @__PURE__ */ jsx4(
|
|
819
|
+
"button",
|
|
820
|
+
{
|
|
821
|
+
type: "button",
|
|
822
|
+
onClick: submit,
|
|
823
|
+
disabled: !canSend,
|
|
824
|
+
"aria-label": sendLabel,
|
|
825
|
+
className: cn(
|
|
826
|
+
"ml-auto flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground",
|
|
827
|
+
"transition-opacity hover:opacity-90 disabled:opacity-40"
|
|
828
|
+
),
|
|
829
|
+
children: busy ? /* @__PURE__ */ jsx4(Loader2, { className: "size-4 animate-spin" }) : /* @__PURE__ */ jsx4(ArrowUp, { className: "size-4" })
|
|
830
|
+
}
|
|
831
|
+
)
|
|
832
|
+
] })
|
|
833
|
+
]
|
|
834
|
+
}
|
|
835
|
+
);
|
|
836
|
+
}
|
|
837
|
+
|
|
483
838
|
// src/chat/artifact-agent-dock.tsx
|
|
484
|
-
import * as
|
|
839
|
+
import * as React3 from "react";
|
|
485
840
|
import { Sparkles as Sparkles2, Send, Square, X } from "lucide-react";
|
|
486
841
|
import { ChatMessage } from "@tangle-network/ui/chat";
|
|
487
|
-
import { jsx as
|
|
842
|
+
import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
488
843
|
function defaultScopeLabel(scope) {
|
|
489
844
|
if (scope.label) return scope.label;
|
|
490
845
|
switch (scope.kind) {
|
|
@@ -530,23 +885,23 @@ function ArtifactAgentDock({
|
|
|
530
885
|
onError,
|
|
531
886
|
className
|
|
532
887
|
}) {
|
|
533
|
-
const [threadId, setThreadId] =
|
|
534
|
-
const [messages, setMessages] =
|
|
535
|
-
const [composer, setComposer] =
|
|
536
|
-
const [streamContent, setStreamContent] =
|
|
537
|
-
const [sending, setSending] =
|
|
538
|
-
const [loading, setLoading] =
|
|
539
|
-
const abortRef =
|
|
540
|
-
const scrollRef =
|
|
541
|
-
const scopeTokenRef =
|
|
542
|
-
const reportError =
|
|
888
|
+
const [threadId, setThreadId] = React3.useState(null);
|
|
889
|
+
const [messages, setMessages] = React3.useState([]);
|
|
890
|
+
const [composer, setComposer] = React3.useState(defaultPrompt ?? "");
|
|
891
|
+
const [streamContent, setStreamContent] = React3.useState("");
|
|
892
|
+
const [sending, setSending] = React3.useState(false);
|
|
893
|
+
const [loading, setLoading] = React3.useState(false);
|
|
894
|
+
const abortRef = React3.useRef(null);
|
|
895
|
+
const scrollRef = React3.useRef(null);
|
|
896
|
+
const scopeTokenRef = React3.useRef(0);
|
|
897
|
+
const reportError = React3.useCallback(
|
|
543
898
|
(message) => {
|
|
544
899
|
if (onError) onError(message);
|
|
545
900
|
else if (typeof console !== "undefined") console.error("[ArtifactAgentDock]", message);
|
|
546
901
|
},
|
|
547
902
|
[onError]
|
|
548
903
|
);
|
|
549
|
-
|
|
904
|
+
React3.useEffect(() => {
|
|
550
905
|
if (!open) return;
|
|
551
906
|
scopeTokenRef.current += 1;
|
|
552
907
|
abortRef.current?.abort();
|
|
@@ -582,11 +937,11 @@ function ArtifactAgentDock({
|
|
|
582
937
|
cancelled = true;
|
|
583
938
|
};
|
|
584
939
|
}, [open, scope.kind, scope.key, transport, reportError]);
|
|
585
|
-
|
|
940
|
+
React3.useEffect(() => {
|
|
586
941
|
if (!scrollRef.current) return;
|
|
587
942
|
scrollRef.current.scrollTop = scrollRef.current.scrollHeight;
|
|
588
943
|
}, [messages.length, streamContent]);
|
|
589
|
-
const send =
|
|
944
|
+
const send = React3.useCallback(async () => {
|
|
590
945
|
const text = composer.trim();
|
|
591
946
|
if (!text || !threadId || sending) return;
|
|
592
947
|
const token = scopeTokenRef.current;
|
|
@@ -636,7 +991,7 @@ function ArtifactAgentDock({
|
|
|
636
991
|
if (abortRef.current === controller) abortRef.current = null;
|
|
637
992
|
}
|
|
638
993
|
}, [composer, threadId, sending, transport, reportError]);
|
|
639
|
-
const cancel =
|
|
994
|
+
const cancel = React3.useCallback(() => {
|
|
640
995
|
if (threadId && transport.cancel) {
|
|
641
996
|
try {
|
|
642
997
|
void Promise.resolve(transport.cancel({ threadId })).catch(() => {
|
|
@@ -650,7 +1005,7 @@ function ArtifactAgentDock({
|
|
|
650
1005
|
}, [threadId, transport]);
|
|
651
1006
|
if (!open) return null;
|
|
652
1007
|
const heading = defaultScopeLabel(scope);
|
|
653
|
-
return /* @__PURE__ */
|
|
1008
|
+
return /* @__PURE__ */ jsxs5(
|
|
654
1009
|
"aside",
|
|
655
1010
|
{
|
|
656
1011
|
className: cn(
|
|
@@ -659,38 +1014,38 @@ function ArtifactAgentDock({
|
|
|
659
1014
|
),
|
|
660
1015
|
"aria-label": `Agent chat about ${heading}`,
|
|
661
1016
|
children: [
|
|
662
|
-
/* @__PURE__ */
|
|
663
|
-
/* @__PURE__ */
|
|
664
|
-
/* @__PURE__ */
|
|
665
|
-
/* @__PURE__ */
|
|
666
|
-
/* @__PURE__ */
|
|
667
|
-
/* @__PURE__ */
|
|
1017
|
+
/* @__PURE__ */ jsxs5("header", { className: "flex items-center justify-between border-b border-[var(--md3-outline-variant)] bg-surface-container-low px-4 py-3", children: [
|
|
1018
|
+
/* @__PURE__ */ jsxs5("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1019
|
+
/* @__PURE__ */ jsx5(Sparkles2, { className: "h-4 w-4 shrink-0 text-muted-foreground" }),
|
|
1020
|
+
/* @__PURE__ */ jsxs5("div", { className: "min-w-0", children: [
|
|
1021
|
+
/* @__PURE__ */ jsx5("div", { className: "text-[10px] font-medium uppercase tracking-wider text-muted-foreground", children: "Discussing" }),
|
|
1022
|
+
/* @__PURE__ */ jsx5("div", { className: "truncate text-sm font-semibold text-foreground", children: heading })
|
|
668
1023
|
] })
|
|
669
1024
|
] }),
|
|
670
|
-
/* @__PURE__ */
|
|
1025
|
+
/* @__PURE__ */ jsx5(
|
|
671
1026
|
"button",
|
|
672
1027
|
{
|
|
673
1028
|
type: "button",
|
|
674
1029
|
onClick: () => onOpenChange(false),
|
|
675
1030
|
"aria-label": "Close artifact chat",
|
|
676
1031
|
className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground",
|
|
677
|
-
children: /* @__PURE__ */
|
|
1032
|
+
children: /* @__PURE__ */ jsx5(X, { className: "h-4 w-4" })
|
|
678
1033
|
}
|
|
679
1034
|
)
|
|
680
1035
|
] }),
|
|
681
|
-
/* @__PURE__ */
|
|
682
|
-
/* @__PURE__ */
|
|
683
|
-
/* @__PURE__ */
|
|
1036
|
+
/* @__PURE__ */ jsx5("div", { ref: scrollRef, className: "flex-1 overflow-y-auto px-3 py-4", children: loading ? /* @__PURE__ */ jsx5("div", { className: "px-3 py-8 text-center text-xs text-muted-foreground", children: "Loading conversation\u2026" }) : messages.length === 0 && !streamContent ? /* @__PURE__ */ jsxs5("div", { className: "px-3 py-12 text-center", children: [
|
|
1037
|
+
/* @__PURE__ */ jsx5(Sparkles2, { className: "mx-auto mb-3 h-5 w-5 text-muted-foreground/40" }),
|
|
1038
|
+
/* @__PURE__ */ jsxs5("p", { className: "text-sm text-foreground", children: [
|
|
684
1039
|
"Ask the agent about this ",
|
|
685
1040
|
scope.kind === "vault-file" ? "document" : scope.kind,
|
|
686
1041
|
"."
|
|
687
1042
|
] }),
|
|
688
|
-
/* @__PURE__ */
|
|
689
|
-
] }) : /* @__PURE__ */
|
|
690
|
-
messages.map((m) => /* @__PURE__ */
|
|
691
|
-
streamContent && /* @__PURE__ */
|
|
1043
|
+
/* @__PURE__ */ jsx5("p", { className: "mt-1 text-xs text-muted-foreground", children: "It can read the current contents and propose edits, rewrites, or follow-ups." })
|
|
1044
|
+
] }) : /* @__PURE__ */ jsxs5("div", { className: "space-y-3", children: [
|
|
1045
|
+
messages.map((m) => /* @__PURE__ */ jsx5(ChatMessage, { role: m.role, content: m.content, timestamp: m.createdAt }, m.id)),
|
|
1046
|
+
streamContent && /* @__PURE__ */ jsx5(ChatMessage, { role: "assistant", content: streamContent, isStreaming: true })
|
|
692
1047
|
] }) }),
|
|
693
|
-
/* @__PURE__ */
|
|
1048
|
+
/* @__PURE__ */ jsx5(
|
|
694
1049
|
"form",
|
|
695
1050
|
{
|
|
696
1051
|
className: "border-t border-[var(--md3-outline-variant)] bg-surface-container-low p-3",
|
|
@@ -698,8 +1053,8 @@ function ArtifactAgentDock({
|
|
|
698
1053
|
e.preventDefault();
|
|
699
1054
|
void send();
|
|
700
1055
|
},
|
|
701
|
-
children: /* @__PURE__ */
|
|
702
|
-
/* @__PURE__ */
|
|
1056
|
+
children: /* @__PURE__ */ jsxs5("div", { className: "flex items-end gap-2", children: [
|
|
1057
|
+
/* @__PURE__ */ jsx5(
|
|
703
1058
|
"textarea",
|
|
704
1059
|
{
|
|
705
1060
|
value: composer,
|
|
@@ -716,23 +1071,23 @@ function ArtifactAgentDock({
|
|
|
716
1071
|
className: "min-h-[44px] flex-1 resize-none rounded-[20px] border border-[var(--md3-outline-variant)] bg-surface-dim px-3.5 py-2 text-sm text-foreground placeholder:text-muted-foreground transition-colors focus:outline-none focus:border-[var(--border-accent)] disabled:opacity-50"
|
|
717
1072
|
}
|
|
718
1073
|
),
|
|
719
|
-
sending ? /* @__PURE__ */
|
|
1074
|
+
sending ? /* @__PURE__ */ jsx5(
|
|
720
1075
|
"button",
|
|
721
1076
|
{
|
|
722
1077
|
type: "button",
|
|
723
1078
|
onClick: cancel,
|
|
724
1079
|
"aria-label": "Cancel",
|
|
725
1080
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-md text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground",
|
|
726
|
-
children: /* @__PURE__ */
|
|
1081
|
+
children: /* @__PURE__ */ jsx5(Square, { className: "h-4 w-4" })
|
|
727
1082
|
}
|
|
728
|
-
) : /* @__PURE__ */
|
|
1083
|
+
) : /* @__PURE__ */ jsx5(
|
|
729
1084
|
"button",
|
|
730
1085
|
{
|
|
731
1086
|
type: "submit",
|
|
732
1087
|
disabled: !composer.trim() || !threadId,
|
|
733
1088
|
"aria-label": "Send",
|
|
734
1089
|
className: "inline-flex h-9 w-9 items-center justify-center rounded-full bg-primary text-primary-foreground transition-colors hover:bg-primary/90 disabled:opacity-50",
|
|
735
|
-
children: /* @__PURE__ */
|
|
1090
|
+
children: /* @__PURE__ */ jsx5(Send, { className: "h-4 w-4" })
|
|
736
1091
|
}
|
|
737
1092
|
)
|
|
738
1093
|
] })
|
|
@@ -821,12 +1176,13 @@ function createFetchTransport(opts) {
|
|
|
821
1176
|
export {
|
|
822
1177
|
DEFAULT_REASONING_LEVEL_OPTIONS,
|
|
823
1178
|
ReasoningLevelPicker,
|
|
824
|
-
HARNESS_MODEL_POLICIES,
|
|
825
|
-
modelProvider,
|
|
826
1179
|
isModelCompatibleWithHarness,
|
|
827
1180
|
snapModelToHarness,
|
|
1181
|
+
modelProvider,
|
|
828
1182
|
snapHarnessToModel,
|
|
1183
|
+
AgentProfilePicker,
|
|
829
1184
|
AgentSessionControls,
|
|
1185
|
+
AgentComposer,
|
|
830
1186
|
ArtifactAgentDock,
|
|
831
1187
|
createFetchTransport,
|
|
832
1188
|
AgentTimeline,
|