langchain_agentx_stream_ui 0.1.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 +236 -0
- package/dist/AskUserQuestionToolBody-CyuNy_k5.d.ts +33 -0
- package/dist/MarkdownBlock-3iEW0Ubm.d.ts +100 -0
- package/dist/chunk-4RIOBLGB.js +666 -0
- package/dist/chunk-4RIOBLGB.js.map +1 -0
- package/dist/chunk-DP7V33X7.js +13 -0
- package/dist/chunk-DP7V33X7.js.map +1 -0
- package/dist/chunk-G2KYJCMM.js +5171 -0
- package/dist/chunk-G2KYJCMM.js.map +1 -0
- package/dist/chunk-MHK53ZHC.js +972 -0
- package/dist/chunk-MHK53ZHC.js.map +1 -0
- package/dist/chunk-W6QQHTJ4.js +785 -0
- package/dist/chunk-W6QQHTJ4.js.map +1 -0
- package/dist/chunk-WM6Y6APP.js +411 -0
- package/dist/chunk-WM6Y6APP.js.map +1 -0
- package/dist/default.css +1364 -0
- package/dist/index.d.ts +650 -0
- package/dist/index.js +743 -0
- package/dist/index.js.map +1 -0
- package/dist/multi-session-CviqerRl.d.ts +494 -0
- package/dist/multi-session.d.ts +7 -0
- package/dist/multi-session.js +21 -0
- package/dist/multi-session.js.map +1 -0
- package/dist/nodes-DqhaBW7M.d.ts +195 -0
- package/dist/sessionViewOptions-DLSFRQwZ.d.ts +158 -0
- package/dist/tools-presentation.d.ts +14 -0
- package/dist/tools-presentation.js +37 -0
- package/dist/tools-presentation.js.map +1 -0
- package/dist/tools.d.ts +21 -0
- package/dist/tools.js +43 -0
- package/dist/tools.js.map +1 -0
- package/dist/types-aXj5TYSP.d.ts +33 -0
- package/dist/virtual.d.ts +36 -0
- package/dist/virtual.js +19 -0
- package/dist/virtual.js.map +1 -0
- package/package.json +88 -0
|
@@ -0,0 +1,972 @@
|
|
|
1
|
+
import {
|
|
2
|
+
BodyBlockList,
|
|
3
|
+
DiffView,
|
|
4
|
+
MAX_PREVIEW_LINES,
|
|
5
|
+
MarkdownBlock,
|
|
6
|
+
TruncatedContent,
|
|
7
|
+
WRITE_PREVIEW_LINES,
|
|
8
|
+
buildBashBodyBlocks,
|
|
9
|
+
countLines,
|
|
10
|
+
displayPath,
|
|
11
|
+
formatDiffFromStrings,
|
|
12
|
+
formatSearchResultBody,
|
|
13
|
+
resolveEditDiffText,
|
|
14
|
+
truncateCommand,
|
|
15
|
+
truncateLines
|
|
16
|
+
} from "./chunk-4RIOBLGB.js";
|
|
17
|
+
|
|
18
|
+
// src/view/tools/toolNames.ts
|
|
19
|
+
var Read = "Read";
|
|
20
|
+
var Write = "Write";
|
|
21
|
+
var Edit = "Edit";
|
|
22
|
+
var Glob = "Glob";
|
|
23
|
+
var Grep = "Grep";
|
|
24
|
+
var Bash = "Bash";
|
|
25
|
+
var Skill = "Skill";
|
|
26
|
+
var Agent = "Agent";
|
|
27
|
+
var AskUserQuestion = "AskUserQuestion";
|
|
28
|
+
var WebSearch = "WebSearch";
|
|
29
|
+
var WebFetch = "WebFetch";
|
|
30
|
+
var TaskCreate = "TaskCreate";
|
|
31
|
+
var TaskUpdate = "TaskUpdate";
|
|
32
|
+
var TaskList = "TaskList";
|
|
33
|
+
var TaskGet = "TaskGet";
|
|
34
|
+
var TaskOutput = "TaskOutput";
|
|
35
|
+
var TaskStop = "TaskStop";
|
|
36
|
+
var SILENT_TASK_TOOL_NAMES = [
|
|
37
|
+
TaskCreate,
|
|
38
|
+
TaskGet,
|
|
39
|
+
TaskList,
|
|
40
|
+
TaskUpdate
|
|
41
|
+
];
|
|
42
|
+
var INTERNAL_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
43
|
+
...SILENT_TASK_TOOL_NAMES,
|
|
44
|
+
TaskOutput,
|
|
45
|
+
TaskStop
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
// src/view/tools/presentation/agentProgressRenderer.ts
|
|
49
|
+
var AGENT_PROGRESS_GUTTER = " \u23BF ";
|
|
50
|
+
var AGENT_PROGRESS_INDENT = " ";
|
|
51
|
+
function truncatePreview(text, maxChars = 80) {
|
|
52
|
+
const trimmed = text.trim();
|
|
53
|
+
if (trimmed.length <= maxChars) return trimmed;
|
|
54
|
+
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
55
|
+
}
|
|
56
|
+
var READ_TOOLS = /* @__PURE__ */ new Set(["Read"]);
|
|
57
|
+
var SEARCH_TOOLS = /* @__PURE__ */ new Set(["Glob", "Grep", "SemanticSearch", "Search"]);
|
|
58
|
+
var BASH_TOOLS = /* @__PURE__ */ new Set(["Bash"]);
|
|
59
|
+
function toolInputRecord(input) {
|
|
60
|
+
if (input != null && typeof input === "object" && !Array.isArray(input)) {
|
|
61
|
+
return input;
|
|
62
|
+
}
|
|
63
|
+
return {};
|
|
64
|
+
}
|
|
65
|
+
function formatSubagentToolProgressLine(toolName, options = {}) {
|
|
66
|
+
const name = toolName.trim();
|
|
67
|
+
const inp = toolInputRecord(options.toolInput);
|
|
68
|
+
if (name === "Bash") {
|
|
69
|
+
const command = String(inp.command ?? inp.description ?? "").trim();
|
|
70
|
+
if (command) return `Bash(${truncateCommand(command)})`;
|
|
71
|
+
}
|
|
72
|
+
if (name === "Read") {
|
|
73
|
+
const path = String(inp.path ?? inp.file_path ?? "").trim();
|
|
74
|
+
if (path) return `Read(${truncatePreview(path, 60)})`;
|
|
75
|
+
}
|
|
76
|
+
if (name === "Glob" || name === "Grep") {
|
|
77
|
+
const pattern = String(inp.pattern ?? inp.glob_pattern ?? "").trim();
|
|
78
|
+
const path = String(inp.path ?? inp.glob ?? "").trim();
|
|
79
|
+
if (pattern && path) {
|
|
80
|
+
return `${name}(${truncatePreview(pattern, 40)}, ${truncatePreview(path, 40)})`;
|
|
81
|
+
}
|
|
82
|
+
if (pattern) return `${name}(${truncatePreview(pattern, 60)})`;
|
|
83
|
+
if (path) return `${name}(${truncatePreview(path, 60)})`;
|
|
84
|
+
}
|
|
85
|
+
const summary = (options.summary ?? "").trim();
|
|
86
|
+
const callingLower = `calling ${name.toLowerCase()}`;
|
|
87
|
+
if (summary && summary.toLowerCase() !== callingLower) {
|
|
88
|
+
return summary;
|
|
89
|
+
}
|
|
90
|
+
return name;
|
|
91
|
+
}
|
|
92
|
+
function formatSubagentProgressLine(entry) {
|
|
93
|
+
return formatSubagentToolProgressLine(entry.toolName, {
|
|
94
|
+
summary: entry.summary,
|
|
95
|
+
toolInput: entry.toolInput
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
function formatGroupText(toolName, display, count, isRead, isSearch, isRunning) {
|
|
99
|
+
if (count > 1) {
|
|
100
|
+
if (isRead) {
|
|
101
|
+
const verb = isRunning ? "Reading" : "Read";
|
|
102
|
+
const noun = count === 1 ? "file" : "files";
|
|
103
|
+
return `${verb} ${count} ${noun}`;
|
|
104
|
+
}
|
|
105
|
+
if (isSearch) {
|
|
106
|
+
return `${toolName} ${count} times`;
|
|
107
|
+
}
|
|
108
|
+
return `${toolName} ${count} times`;
|
|
109
|
+
}
|
|
110
|
+
return display;
|
|
111
|
+
}
|
|
112
|
+
function groupProgressEntries(entries, isRunning) {
|
|
113
|
+
const raw = entries.map((entry) => ({
|
|
114
|
+
toolName: entry.toolName,
|
|
115
|
+
display: formatSubagentProgressLine(entry),
|
|
116
|
+
isError: false
|
|
117
|
+
}));
|
|
118
|
+
const grouped = [];
|
|
119
|
+
let currentTool = null;
|
|
120
|
+
let currentDisplay = null;
|
|
121
|
+
let currentCount = 0;
|
|
122
|
+
let currentIsRead = false;
|
|
123
|
+
let currentIsSearch = false;
|
|
124
|
+
const flush = () => {
|
|
125
|
+
if (currentTool == null || currentCount === 0) return;
|
|
126
|
+
grouped.push({
|
|
127
|
+
text: formatGroupText(
|
|
128
|
+
currentTool,
|
|
129
|
+
currentDisplay ?? currentTool,
|
|
130
|
+
currentCount,
|
|
131
|
+
currentIsRead,
|
|
132
|
+
currentIsSearch,
|
|
133
|
+
isRunning
|
|
134
|
+
),
|
|
135
|
+
toolUseCount: currentCount
|
|
136
|
+
});
|
|
137
|
+
currentTool = null;
|
|
138
|
+
currentDisplay = null;
|
|
139
|
+
currentCount = 0;
|
|
140
|
+
currentIsRead = false;
|
|
141
|
+
currentIsSearch = false;
|
|
142
|
+
};
|
|
143
|
+
for (const { toolName, display } of raw) {
|
|
144
|
+
const isRead = READ_TOOLS.has(toolName);
|
|
145
|
+
const isSearch = SEARCH_TOOLS.has(toolName);
|
|
146
|
+
const isBash = BASH_TOOLS.has(toolName);
|
|
147
|
+
const sameGroup = !isBash && currentTool === toolName && currentIsRead === isRead && currentIsSearch === isSearch;
|
|
148
|
+
if (sameGroup) {
|
|
149
|
+
currentCount += 1;
|
|
150
|
+
} else {
|
|
151
|
+
flush();
|
|
152
|
+
currentTool = toolName;
|
|
153
|
+
currentDisplay = display;
|
|
154
|
+
currentCount = 1;
|
|
155
|
+
currentIsRead = isRead;
|
|
156
|
+
currentIsSearch = isSearch;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
flush();
|
|
160
|
+
return grouped;
|
|
161
|
+
}
|
|
162
|
+
function processAgentProgressLines(entries, options) {
|
|
163
|
+
const processed = groupProgressEntries(entries, options.isRunning);
|
|
164
|
+
if (options.maxVisible >= processed.length) {
|
|
165
|
+
return { visible: processed, hiddenToolUseCount: 0 };
|
|
166
|
+
}
|
|
167
|
+
const visible = processed.slice(-options.maxVisible);
|
|
168
|
+
const hidden = processed.slice(0, processed.length - options.maxVisible);
|
|
169
|
+
const hiddenToolUseCount = hidden.reduce((sum, line) => sum + line.toolUseCount, 0);
|
|
170
|
+
return { visible, hiddenToolUseCount };
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// src/view/tools/presentation/agentHelpers.ts
|
|
174
|
+
var DONE_LINE_RE = /Done \((.+?)\)/i;
|
|
175
|
+
var AGENT_STEPS_RE = /(\d+)\s+tool uses?/i;
|
|
176
|
+
var AGENT_MAX_BODY_LINES = 25;
|
|
177
|
+
var AGENT_PROGRESS_TAIL_LINES = 3;
|
|
178
|
+
function truncatePreview2(text, maxChars = 80) {
|
|
179
|
+
const trimmed = text.trim();
|
|
180
|
+
if (trimmed.length <= maxChars) return trimmed;
|
|
181
|
+
return `${trimmed.slice(0, maxChars)}\u2026`;
|
|
182
|
+
}
|
|
183
|
+
function formatAgentTitle(input, display) {
|
|
184
|
+
const inp = input != null && typeof input === "object" && !Array.isArray(input) ? input : {};
|
|
185
|
+
const d = display != null && typeof display === "object" && !Array.isArray(display) ? display : null;
|
|
186
|
+
const merged = { ...inp };
|
|
187
|
+
if (d?.subagent_type) merged.subagent_type = d.subagent_type;
|
|
188
|
+
if (d?.description) merged.description = d.description;
|
|
189
|
+
const subagent = String(merged.subagent_type ?? "general-purpose").trim();
|
|
190
|
+
const desc = String(merged.description ?? merged.prompt ?? "").trim();
|
|
191
|
+
let title = desc ? `${subagent}(${truncatePreview2(desc)})` : subagent;
|
|
192
|
+
const model = merged.model;
|
|
193
|
+
if (model) {
|
|
194
|
+
const modelStr = String(model).trim();
|
|
195
|
+
if (modelStr) title = `${title} ${modelStr}`;
|
|
196
|
+
}
|
|
197
|
+
return title;
|
|
198
|
+
}
|
|
199
|
+
function parseAgentDoneSummary(output) {
|
|
200
|
+
const text = output.trim();
|
|
201
|
+
if (!text) return null;
|
|
202
|
+
const doneMatch = text.match(DONE_LINE_RE);
|
|
203
|
+
if (doneMatch) return `Done (${doneMatch[1].trim()})`;
|
|
204
|
+
const stepsMatch = text.match(AGENT_STEPS_RE);
|
|
205
|
+
if (stepsMatch) return `Done (${stepsMatch[1]} tool uses)`;
|
|
206
|
+
const first = text.split("\n", 1)[0]?.trim() ?? "";
|
|
207
|
+
if (first.toLowerCase().startsWith("done")) return first;
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function buildAgentBodyText(display, summary) {
|
|
211
|
+
const d = display != null && typeof display === "object" && !Array.isArray(display) ? display : null;
|
|
212
|
+
let done = null;
|
|
213
|
+
if (d?.total_steps != null && d.status === "completed") {
|
|
214
|
+
done = `Done (${d.total_steps} tool uses)`;
|
|
215
|
+
} else {
|
|
216
|
+
done = parseAgentDoneSummary(summary);
|
|
217
|
+
}
|
|
218
|
+
if (done) {
|
|
219
|
+
let rest = summary.trim();
|
|
220
|
+
if (rest.startsWith(done)) {
|
|
221
|
+
rest = rest.slice(done.length).trimStart();
|
|
222
|
+
}
|
|
223
|
+
const parts = [done];
|
|
224
|
+
if (rest) {
|
|
225
|
+
const { text: truncated2, truncated: was2 } = truncateLines(
|
|
226
|
+
rest,
|
|
227
|
+
AGENT_MAX_BODY_LINES
|
|
228
|
+
);
|
|
229
|
+
parts.push(was2 ? `${truncated2}
|
|
230
|
+
\u2026 \u8D85\u8FC7 ${AGENT_MAX_BODY_LINES} \u884C\uFF0C\u5DF2\u622A\u65AD` : truncated2);
|
|
231
|
+
}
|
|
232
|
+
return parts.join("\n");
|
|
233
|
+
}
|
|
234
|
+
const text = summary.trim();
|
|
235
|
+
if (!text) return "(done)";
|
|
236
|
+
const { text: truncated, truncated: was } = truncateLines(text, AGENT_MAX_BODY_LINES);
|
|
237
|
+
return was ? `${truncated}
|
|
238
|
+
\u2026 \u8D85\u8FC7 ${AGENT_MAX_BODY_LINES} \u884C\uFF0C\u5DF2\u622A\u65AD` : truncated;
|
|
239
|
+
}
|
|
240
|
+
function formatSubagentProgressLine2(entry) {
|
|
241
|
+
return formatSubagentToolProgressLine(entry.toolName, {
|
|
242
|
+
summary: entry.summary,
|
|
243
|
+
toolInput: entry.toolInput
|
|
244
|
+
});
|
|
245
|
+
}
|
|
246
|
+
function buildAgentTranscriptText(display, subagentProgress) {
|
|
247
|
+
const d = display != null && typeof display === "object" && !Array.isArray(display) ? display : null;
|
|
248
|
+
const toolCalls = d?.tool_calls;
|
|
249
|
+
if (Array.isArray(toolCalls) && toolCalls.length > 0) {
|
|
250
|
+
return toolCalls.map((row) => {
|
|
251
|
+
const item = row;
|
|
252
|
+
const name = String(item.tool_name ?? "tool");
|
|
253
|
+
const summary = String(item.summary ?? "").trim();
|
|
254
|
+
return summary ? `${name}: ${summary}` : name;
|
|
255
|
+
}).join("\n");
|
|
256
|
+
}
|
|
257
|
+
if (subagentProgress?.length) {
|
|
258
|
+
return subagentProgress.map(formatSubagentProgressLine2).join("\n");
|
|
259
|
+
}
|
|
260
|
+
return "";
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// src/view/tools/agent/AgentProgressLines.tsx
|
|
264
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
265
|
+
function AgentProgressLines({
|
|
266
|
+
entries,
|
|
267
|
+
mode,
|
|
268
|
+
maxVisible = AGENT_PROGRESS_TAIL_LINES,
|
|
269
|
+
onExpand
|
|
270
|
+
}) {
|
|
271
|
+
if (entries.length === 0) return null;
|
|
272
|
+
const isRunning = entries.some((e) => e.status === "running");
|
|
273
|
+
const limit = mode === "full" ? entries.length : maxVisible;
|
|
274
|
+
const { visible, hiddenToolUseCount } = processAgentProgressLines(entries, {
|
|
275
|
+
isRunning,
|
|
276
|
+
maxVisible: limit
|
|
277
|
+
});
|
|
278
|
+
return /* @__PURE__ */ jsxs("div", { className: "lax-agent-progress", "data-testid": "lax-agent-progress", children: [
|
|
279
|
+
visible.map((line, index) => /* @__PURE__ */ jsxs(
|
|
280
|
+
"div",
|
|
281
|
+
{
|
|
282
|
+
className: "lax-agent-progress__line",
|
|
283
|
+
children: [
|
|
284
|
+
/* @__PURE__ */ jsx("span", { className: "lax-agent-progress__gutter", "aria-hidden": true, children: index === 0 ? AGENT_PROGRESS_GUTTER : AGENT_PROGRESS_INDENT }),
|
|
285
|
+
/* @__PURE__ */ jsx("span", { className: "lax-agent-progress__text", children: line.text })
|
|
286
|
+
]
|
|
287
|
+
},
|
|
288
|
+
`${index}:${line.text}`
|
|
289
|
+
)),
|
|
290
|
+
hiddenToolUseCount > 0 && mode !== "full" ? /* @__PURE__ */ jsxs("div", { className: "lax-agent-progress__line lax-agent-progress__line--more", children: [
|
|
291
|
+
/* @__PURE__ */ jsx("span", { className: "lax-agent-progress__gutter", "aria-hidden": true, children: AGENT_PROGRESS_INDENT }),
|
|
292
|
+
/* @__PURE__ */ jsxs(
|
|
293
|
+
"button",
|
|
294
|
+
{
|
|
295
|
+
type: "button",
|
|
296
|
+
className: "lax-agent-progress__more",
|
|
297
|
+
onClick: onExpand,
|
|
298
|
+
children: [
|
|
299
|
+
"+",
|
|
300
|
+
hiddenToolUseCount,
|
|
301
|
+
" more tool ",
|
|
302
|
+
hiddenToolUseCount === 1 ? "use" : "uses"
|
|
303
|
+
]
|
|
304
|
+
}
|
|
305
|
+
)
|
|
306
|
+
] }) : null
|
|
307
|
+
] });
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// src/view/tools/agent/AgentToolBody.tsx
|
|
311
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
312
|
+
function AgentToolBody({
|
|
313
|
+
result,
|
|
314
|
+
bodyMode,
|
|
315
|
+
onBodyModeChange,
|
|
316
|
+
status,
|
|
317
|
+
subagentProgress
|
|
318
|
+
}) {
|
|
319
|
+
if (result?.error) {
|
|
320
|
+
return /* @__PURE__ */ jsx2("div", { className: "lax-tool-body lax-tool-body--agent", children: /* @__PURE__ */ jsx2("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx2("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
321
|
+
}
|
|
322
|
+
const progress = subagentProgress ?? [];
|
|
323
|
+
const bodyText = buildAgentBodyText(result?.display, result?.summary ?? "");
|
|
324
|
+
const transcript = buildAgentTranscriptText(result?.display, progress);
|
|
325
|
+
const showRunningProgress = status === "running" && progress.length > 0;
|
|
326
|
+
const showDoneSummary = status !== "running" && bodyText.length > 0;
|
|
327
|
+
const showTranscript = status === "done" && bodyMode === "full" && transcript.length > 0;
|
|
328
|
+
if (!showRunningProgress && !showDoneSummary && !showTranscript) {
|
|
329
|
+
return /* @__PURE__ */ jsx2("div", { className: "lax-tool-body lax-tool-body--agent", children: /* @__PURE__ */ jsx2("div", { className: "lax-tool-body__block", "data-variant": "dim", children: /* @__PURE__ */ jsx2("pre", { className: "lax-tool-body__text", children: "(running)" }) }) });
|
|
330
|
+
}
|
|
331
|
+
return /* @__PURE__ */ jsxs2("div", { className: "lax-tool-body lax-tool-body--agent", children: [
|
|
332
|
+
showRunningProgress ? /* @__PURE__ */ jsx2(
|
|
333
|
+
AgentProgressLines,
|
|
334
|
+
{
|
|
335
|
+
entries: progress,
|
|
336
|
+
mode: bodyMode,
|
|
337
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
338
|
+
}
|
|
339
|
+
) : null,
|
|
340
|
+
showDoneSummary ? /* @__PURE__ */ jsx2(
|
|
341
|
+
TruncatedContent,
|
|
342
|
+
{
|
|
343
|
+
text: bodyText,
|
|
344
|
+
mode: bodyMode,
|
|
345
|
+
maxLines: 12,
|
|
346
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
347
|
+
}
|
|
348
|
+
) : null,
|
|
349
|
+
showTranscript ? /* @__PURE__ */ jsxs2("div", { className: "lax-agent-progress lax-agent-progress--transcript", children: [
|
|
350
|
+
/* @__PURE__ */ jsx2("div", { className: "lax-agent-progress__label", children: "Transcript" }),
|
|
351
|
+
/* @__PURE__ */ jsx2(TruncatedContent, { text: transcript, mode: "full" })
|
|
352
|
+
] }) : null
|
|
353
|
+
] });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// src/view/tools/displayRecord.ts
|
|
357
|
+
function asDisplayRecord(display) {
|
|
358
|
+
if (display != null && typeof display === "object" && !Array.isArray(display)) {
|
|
359
|
+
return display;
|
|
360
|
+
}
|
|
361
|
+
return null;
|
|
362
|
+
}
|
|
363
|
+
function asInputRecord(input) {
|
|
364
|
+
if (input != null && typeof input === "object" && !Array.isArray(input)) {
|
|
365
|
+
return input;
|
|
366
|
+
}
|
|
367
|
+
return {};
|
|
368
|
+
}
|
|
369
|
+
function strField(record, key) {
|
|
370
|
+
const value = record[key];
|
|
371
|
+
return value == null ? "" : String(value).trim();
|
|
372
|
+
}
|
|
373
|
+
function numField(record, key) {
|
|
374
|
+
const value = record[key];
|
|
375
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
376
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
377
|
+
const n = Number(value);
|
|
378
|
+
if (Number.isFinite(n)) return n;
|
|
379
|
+
}
|
|
380
|
+
return void 0;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// src/view/tools/presentation/askUserHelpers.ts
|
|
384
|
+
function formatAskUserDisplayBody(display) {
|
|
385
|
+
const items = display.questions;
|
|
386
|
+
if (!Array.isArray(items) || items.length === 0) return "";
|
|
387
|
+
const lines = [];
|
|
388
|
+
for (const item of items) {
|
|
389
|
+
if (item == null || typeof item !== "object") continue;
|
|
390
|
+
const row = item;
|
|
391
|
+
const header = String(row.header ?? "").trim();
|
|
392
|
+
const question = String(row.question ?? "").trim();
|
|
393
|
+
const answer = String(row.answer ?? "").trim();
|
|
394
|
+
const prefix = header ? `[${header}] ` : "";
|
|
395
|
+
lines.push(`${prefix}${question}`);
|
|
396
|
+
if (answer) lines.push(` \u2192 ${answer}`);
|
|
397
|
+
const selected = row.selected_options;
|
|
398
|
+
if (Array.isArray(selected) && selected.length > 0) {
|
|
399
|
+
for (const label of selected) {
|
|
400
|
+
lines.push(` \xB7 ${String(label)}`);
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
return lines.length > 0 ? lines.join("\n") : "";
|
|
405
|
+
}
|
|
406
|
+
function formatAskUserQuestionsPreview(input) {
|
|
407
|
+
const questions = input.questions;
|
|
408
|
+
if (!Array.isArray(questions) || questions.length === 0) {
|
|
409
|
+
return "(waiting for answers)";
|
|
410
|
+
}
|
|
411
|
+
const lines = [];
|
|
412
|
+
questions.forEach((raw, idx) => {
|
|
413
|
+
if (raw == null || typeof raw !== "object") return;
|
|
414
|
+
const q = raw;
|
|
415
|
+
const header = String(q.header ?? "").trim();
|
|
416
|
+
const qtext = String(q.question ?? "").trim();
|
|
417
|
+
const prefix = header ? `[${header}] ` : "";
|
|
418
|
+
lines.push(`${idx + 1}. ${prefix}${qtext}`);
|
|
419
|
+
const options = q.options;
|
|
420
|
+
if (Array.isArray(options)) {
|
|
421
|
+
for (const opt of options) {
|
|
422
|
+
if (opt != null && typeof opt === "object") {
|
|
423
|
+
const label = String(opt.label ?? "").trim();
|
|
424
|
+
if (label) lines.push(` \xB7 ${label}`);
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
});
|
|
429
|
+
return lines.length > 0 ? lines.join("\n") : "(waiting for answers)";
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
// src/view/tools/ask_user_question/AskUserQuestionToolBody.tsx
|
|
433
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
434
|
+
var MAX_DISPLAY_LINES = 25;
|
|
435
|
+
var MAX_DISPLAY_CHARS = 1200;
|
|
436
|
+
function buildAskUserBody(input, display, summary) {
|
|
437
|
+
const d = asDisplayRecord(display);
|
|
438
|
+
if (d) {
|
|
439
|
+
const displayBody = formatAskUserDisplayBody(d);
|
|
440
|
+
if (displayBody) {
|
|
441
|
+
if (displayBody.length > MAX_DISPLAY_CHARS) {
|
|
442
|
+
const { text: text2, truncated } = truncateLines(displayBody, MAX_DISPLAY_LINES);
|
|
443
|
+
return truncated ? `${text2}
|
|
444
|
+
\u2026 \u5DF2\u622A\u65AD` : text2;
|
|
445
|
+
}
|
|
446
|
+
return displayBody;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
const text = summary.trim();
|
|
450
|
+
if (text) return `Answered: ${text}`;
|
|
451
|
+
return formatAskUserQuestionsPreview(asInputRecord(input));
|
|
452
|
+
}
|
|
453
|
+
function AskUserQuestionToolBody({
|
|
454
|
+
input,
|
|
455
|
+
result,
|
|
456
|
+
bodyMode,
|
|
457
|
+
onBodyModeChange
|
|
458
|
+
}) {
|
|
459
|
+
if (result?.error) {
|
|
460
|
+
return /* @__PURE__ */ jsx3("div", { className: "lax-tool-body lax-tool-body--ask-user", children: /* @__PURE__ */ jsx3("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx3("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
461
|
+
}
|
|
462
|
+
const bodyText = buildAskUserBody(input, result?.display, result?.summary ?? "");
|
|
463
|
+
return /* @__PURE__ */ jsx3("div", { className: "lax-tool-body lax-tool-body--ask-user", children: /* @__PURE__ */ jsx3(
|
|
464
|
+
TruncatedContent,
|
|
465
|
+
{
|
|
466
|
+
text: bodyText,
|
|
467
|
+
mode: bodyMode,
|
|
468
|
+
maxLines: 12,
|
|
469
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
470
|
+
}
|
|
471
|
+
) });
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
// src/view/tools/bash/BashToolBody.tsx
|
|
475
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
476
|
+
function BashToolBody({
|
|
477
|
+
result,
|
|
478
|
+
bodyMode,
|
|
479
|
+
onBodyModeChange
|
|
480
|
+
}) {
|
|
481
|
+
const isError = result?.status === "failed" || Boolean(result?.error);
|
|
482
|
+
const summary = result?.summary ?? "";
|
|
483
|
+
const { blocks, truncated, remainingLines } = buildBashBodyBlocks(
|
|
484
|
+
result?.display,
|
|
485
|
+
summary,
|
|
486
|
+
result?.meta,
|
|
487
|
+
bodyMode,
|
|
488
|
+
isError
|
|
489
|
+
);
|
|
490
|
+
return /* @__PURE__ */ jsxs3("div", { className: "lax-tool-body lax-tool-body--bash", children: [
|
|
491
|
+
/* @__PURE__ */ jsx4(BodyBlockList, { blocks }),
|
|
492
|
+
truncated && bodyMode === "preview" ? /* @__PURE__ */ jsxs3(
|
|
493
|
+
"button",
|
|
494
|
+
{
|
|
495
|
+
type: "button",
|
|
496
|
+
className: "lax-tool-body__expand",
|
|
497
|
+
onClick: () => onBodyModeChange?.("full"),
|
|
498
|
+
children: [
|
|
499
|
+
"+",
|
|
500
|
+
remainingLines,
|
|
501
|
+
" lines (\u70B9\u51FB\u5C55\u5F00)"
|
|
502
|
+
]
|
|
503
|
+
}
|
|
504
|
+
) : null
|
|
505
|
+
] });
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
// src/view/tools/edit/EditToolBody.tsx
|
|
509
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
510
|
+
function EditToolBody({
|
|
511
|
+
input,
|
|
512
|
+
result,
|
|
513
|
+
bodyMode,
|
|
514
|
+
onBodyModeChange
|
|
515
|
+
}) {
|
|
516
|
+
if (result?.error) {
|
|
517
|
+
return /* @__PURE__ */ jsx5("div", { className: "lax-tool-body lax-tool-body--edit", children: /* @__PURE__ */ jsx5("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx5("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
518
|
+
}
|
|
519
|
+
const diff = resolveEditDiffText(
|
|
520
|
+
result?.display,
|
|
521
|
+
input,
|
|
522
|
+
result?.summary ?? ""
|
|
523
|
+
);
|
|
524
|
+
return /* @__PURE__ */ jsx5("div", { className: "lax-tool-body lax-tool-body--edit", children: /* @__PURE__ */ jsx5(
|
|
525
|
+
DiffView,
|
|
526
|
+
{
|
|
527
|
+
diff,
|
|
528
|
+
mode: bodyMode,
|
|
529
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
530
|
+
}
|
|
531
|
+
) });
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
// src/view/tools/glob/GlobToolBody.tsx
|
|
535
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
536
|
+
function buildGlobBodyText(result) {
|
|
537
|
+
const d = asDisplayRecord(result?.display);
|
|
538
|
+
if (d?.type === "file_list") {
|
|
539
|
+
const files = Array.isArray(d.files) ? d.files.map((f) => String(f)) : [];
|
|
540
|
+
const numFiles = typeof d.num_files === "number" ? d.num_files : files.length;
|
|
541
|
+
const summary2 = numFiles > 0 ? `Found ${numFiles} files` : "No files found";
|
|
542
|
+
if (files.length > 0) {
|
|
543
|
+
return formatSearchResultBody(`${summary2}
|
|
544
|
+
${files.join("\n")}`);
|
|
545
|
+
}
|
|
546
|
+
return summary2;
|
|
547
|
+
}
|
|
548
|
+
if (Array.isArray(d?.files)) {
|
|
549
|
+
const files = d.files.map((f) => String(f));
|
|
550
|
+
const summary2 = `Found ${files.length} files`;
|
|
551
|
+
return formatSearchResultBody(`${summary2}
|
|
552
|
+
${files.join("\n")}`);
|
|
553
|
+
}
|
|
554
|
+
const summary = result?.summary?.trim() ?? "";
|
|
555
|
+
if (summary) return formatSearchResultBody(summary);
|
|
556
|
+
return "(No output)";
|
|
557
|
+
}
|
|
558
|
+
function GlobToolBody({
|
|
559
|
+
result,
|
|
560
|
+
bodyMode,
|
|
561
|
+
onBodyModeChange
|
|
562
|
+
}) {
|
|
563
|
+
if (result?.error) {
|
|
564
|
+
return /* @__PURE__ */ jsx6("div", { className: "lax-tool-body lax-tool-body--glob", children: /* @__PURE__ */ jsx6("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx6("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
565
|
+
}
|
|
566
|
+
const bodyText = buildGlobBodyText(result);
|
|
567
|
+
return /* @__PURE__ */ jsx6("div", { className: "lax-tool-body lax-tool-body--glob", children: /* @__PURE__ */ jsx6(
|
|
568
|
+
TruncatedContent,
|
|
569
|
+
{
|
|
570
|
+
text: bodyText,
|
|
571
|
+
mode: bodyMode,
|
|
572
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
573
|
+
}
|
|
574
|
+
) });
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
// src/view/tools/grep/GrepToolBody.tsx
|
|
578
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
579
|
+
function buildGrepBodyText(result) {
|
|
580
|
+
const d = asDisplayRecord(result?.display);
|
|
581
|
+
if (d?.type === "search_results") {
|
|
582
|
+
const matches = Array.isArray(d.matches) ? d.matches.map((m) => String(m)) : [];
|
|
583
|
+
const numMatches = typeof d.num_matches === "number" ? d.num_matches : matches.length;
|
|
584
|
+
const summary2 = numMatches > 0 ? `Found ${numMatches} matches` : "No matches found";
|
|
585
|
+
if (matches.length > 0) {
|
|
586
|
+
return formatSearchResultBody(`${summary2}
|
|
587
|
+
${matches.join("\n")}`);
|
|
588
|
+
}
|
|
589
|
+
return summary2;
|
|
590
|
+
}
|
|
591
|
+
if (Array.isArray(d?.matches)) {
|
|
592
|
+
const matches = d.matches.map((m) => String(m));
|
|
593
|
+
const summary2 = `Found ${matches.length} matches`;
|
|
594
|
+
return formatSearchResultBody(`${summary2}
|
|
595
|
+
${matches.join("\n")}`);
|
|
596
|
+
}
|
|
597
|
+
const summary = result?.summary?.trim() ?? "";
|
|
598
|
+
if (summary) return formatSearchResultBody(summary);
|
|
599
|
+
return "(No output)";
|
|
600
|
+
}
|
|
601
|
+
function GrepToolBody({
|
|
602
|
+
result,
|
|
603
|
+
bodyMode,
|
|
604
|
+
onBodyModeChange
|
|
605
|
+
}) {
|
|
606
|
+
if (result?.error) {
|
|
607
|
+
return /* @__PURE__ */ jsx7("div", { className: "lax-tool-body lax-tool-body--grep", children: /* @__PURE__ */ jsx7("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx7("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
608
|
+
}
|
|
609
|
+
const bodyText = buildGrepBodyText(result);
|
|
610
|
+
return /* @__PURE__ */ jsx7("div", { className: "lax-tool-body lax-tool-body--grep", children: /* @__PURE__ */ jsx7(
|
|
611
|
+
TruncatedContent,
|
|
612
|
+
{
|
|
613
|
+
text: bodyText,
|
|
614
|
+
mode: bodyMode,
|
|
615
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
616
|
+
}
|
|
617
|
+
) });
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// src/view/tools/read/ReadToolBody.tsx
|
|
621
|
+
import { Fragment, jsx as jsx8, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
622
|
+
var LINES_RANGE_RE = /lines (\d+)-(\d+) of (\d+)/i;
|
|
623
|
+
var READ_LINES_RE = /Read (\d+) lines from/i;
|
|
624
|
+
var EMPTY_RE = /\(empty file\)/i;
|
|
625
|
+
var NOTEBOOK_RE = /Read notebook.*?(\d+) cells/i;
|
|
626
|
+
var IMAGE_RE = /Read image/i;
|
|
627
|
+
var PDF_RE = /Read PDF/i;
|
|
628
|
+
function formatReadBodySummary(display, summary) {
|
|
629
|
+
const d = asDisplayRecord(display);
|
|
630
|
+
if (d?.type === "text") {
|
|
631
|
+
const start = numField(d, "line_start");
|
|
632
|
+
const end = numField(d, "line_end");
|
|
633
|
+
const total = numField(d, "total_lines");
|
|
634
|
+
if (start != null && end != null && total != null) {
|
|
635
|
+
return `Read lines ${start}\u2013${end} of ${total}`;
|
|
636
|
+
}
|
|
637
|
+
const numLines = numField(d, "num_lines");
|
|
638
|
+
if (numLines != null) {
|
|
639
|
+
return `Read ${numLines} lines`;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
if (d?.type === "image") {
|
|
643
|
+
const w = strField(d, "width");
|
|
644
|
+
const h = strField(d, "height");
|
|
645
|
+
if (w && h) return `Read image (${w}\xD7${h})`;
|
|
646
|
+
return "Read image";
|
|
647
|
+
}
|
|
648
|
+
if (d?.type === "pdf") {
|
|
649
|
+
const ps = numField(d, "page_start");
|
|
650
|
+
const pe = numField(d, "page_end");
|
|
651
|
+
if (ps != null && pe != null) {
|
|
652
|
+
return `Read PDF pages ${ps}\u2013${pe}`;
|
|
653
|
+
}
|
|
654
|
+
return "Read PDF";
|
|
655
|
+
}
|
|
656
|
+
const text = summary.trim();
|
|
657
|
+
if (!text) return "(done)";
|
|
658
|
+
if (EMPTY_RE.test(text)) return "Empty file";
|
|
659
|
+
const notebook = text.match(NOTEBOOK_RE);
|
|
660
|
+
if (notebook) return `Read ${notebook[1]} cells`;
|
|
661
|
+
if (IMAGE_RE.test(text)) return text.split("\n", 1)[0]?.trim() || "Read image";
|
|
662
|
+
if (PDF_RE.test(text)) return text.split("\n", 1)[0]?.trim() || "Read PDF";
|
|
663
|
+
const range = text.match(LINES_RANGE_RE);
|
|
664
|
+
if (range) {
|
|
665
|
+
return `Read lines ${range[1]}\u2013${range[2]} of ${range[3]}`;
|
|
666
|
+
}
|
|
667
|
+
const readLines = text.match(READ_LINES_RE);
|
|
668
|
+
if (readLines) return `Read ${readLines[1]} lines`;
|
|
669
|
+
if (text.length > 500) {
|
|
670
|
+
const lineCount = text.split("\n").length;
|
|
671
|
+
return `Read complete (${lineCount} lines in result)`;
|
|
672
|
+
}
|
|
673
|
+
return text.slice(0, 200) || "(done)";
|
|
674
|
+
}
|
|
675
|
+
function extractReadContent(display) {
|
|
676
|
+
const d = asDisplayRecord(display);
|
|
677
|
+
if (!d) return null;
|
|
678
|
+
if (d.type === "markdown" || d.type === "text") {
|
|
679
|
+
const content = strField(d, "content");
|
|
680
|
+
if (content) return content;
|
|
681
|
+
}
|
|
682
|
+
return null;
|
|
683
|
+
}
|
|
684
|
+
function ReadToolBody({
|
|
685
|
+
result,
|
|
686
|
+
bodyMode,
|
|
687
|
+
onBodyModeChange
|
|
688
|
+
}) {
|
|
689
|
+
const display = result?.display ?? null;
|
|
690
|
+
const summary = result?.summary ?? "";
|
|
691
|
+
const bodyLine = formatReadBodySummary(display, summary);
|
|
692
|
+
const content = extractReadContent(display);
|
|
693
|
+
const d = asDisplayRecord(display);
|
|
694
|
+
const isMarkdown = d?.type === "markdown";
|
|
695
|
+
const buildTextBlocks = () => {
|
|
696
|
+
if (!content) return [];
|
|
697
|
+
const lines = content.split("\n");
|
|
698
|
+
const isPreview = bodyMode === "preview" && lines.length > MAX_PREVIEW_LINES;
|
|
699
|
+
const text = isPreview ? lines.slice(0, MAX_PREVIEW_LINES).join("\n") : content;
|
|
700
|
+
return [{ text, variant: "normal" }];
|
|
701
|
+
};
|
|
702
|
+
const textBlocks = buildTextBlocks();
|
|
703
|
+
const hasMore = content && bodyMode === "preview" && content.split("\n").length > MAX_PREVIEW_LINES;
|
|
704
|
+
return /* @__PURE__ */ jsxs4("div", { className: "lax-tool-body lax-tool-body--read", children: [
|
|
705
|
+
/* @__PURE__ */ jsx8("div", { className: "lax-tool-body__summary", children: bodyLine }),
|
|
706
|
+
content ? isMarkdown ? /* @__PURE__ */ jsx8(
|
|
707
|
+
MarkdownBlock,
|
|
708
|
+
{
|
|
709
|
+
text: content,
|
|
710
|
+
mode: bodyMode,
|
|
711
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
712
|
+
}
|
|
713
|
+
) : /* @__PURE__ */ jsxs4(Fragment, { children: [
|
|
714
|
+
/* @__PURE__ */ jsx8(BodyBlockList, { blocks: textBlocks }),
|
|
715
|
+
hasMore ? /* @__PURE__ */ jsxs4(
|
|
716
|
+
"button",
|
|
717
|
+
{
|
|
718
|
+
type: "button",
|
|
719
|
+
className: "lax-tool-body__expand",
|
|
720
|
+
onClick: () => onBodyModeChange?.("full"),
|
|
721
|
+
children: [
|
|
722
|
+
"+",
|
|
723
|
+
content.split("\n").length - MAX_PREVIEW_LINES,
|
|
724
|
+
" lines (\u70B9\u51FB\u5C55\u5F00)"
|
|
725
|
+
]
|
|
726
|
+
}
|
|
727
|
+
) : null
|
|
728
|
+
] }) : null,
|
|
729
|
+
result?.truncated ? /* @__PURE__ */ jsx8("div", { className: "lax-tool-card__truncated", children: "\u7ED3\u679C\u5DF2\u622A\u65AD" }) : null,
|
|
730
|
+
result?.overflow_file ? /* @__PURE__ */ jsxs4("div", { className: "lax-tool-card__overflow", children: [
|
|
731
|
+
"\u5B8C\u6574\u8F93\u51FA\uFF1A",
|
|
732
|
+
/* @__PURE__ */ jsx8("code", { children: result.overflow_file })
|
|
733
|
+
] }) : null
|
|
734
|
+
] });
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
// src/view/tools/skill/SkillToolBody.tsx
|
|
738
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
739
|
+
var MAX_BODY_LINES = 20;
|
|
740
|
+
function SkillToolBody({
|
|
741
|
+
result,
|
|
742
|
+
bodyMode,
|
|
743
|
+
onBodyModeChange
|
|
744
|
+
}) {
|
|
745
|
+
if (result?.error) {
|
|
746
|
+
return /* @__PURE__ */ jsx9("div", { className: "lax-tool-body lax-tool-body--skill", children: /* @__PURE__ */ jsx9("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx9("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
747
|
+
}
|
|
748
|
+
const text = result?.summary?.trim() ?? "";
|
|
749
|
+
if (!text) {
|
|
750
|
+
return /* @__PURE__ */ jsx9("div", { className: "lax-tool-body lax-tool-body--skill", children: /* @__PURE__ */ jsx9("div", { className: "lax-tool-body__block", "data-variant": "dim", children: /* @__PURE__ */ jsx9("pre", { className: "lax-tool-body__text", children: "(done)" }) }) });
|
|
751
|
+
}
|
|
752
|
+
const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES);
|
|
753
|
+
const bodyText = was ? `${truncated}
|
|
754
|
+
\u2026 \u5DF2\u622A\u65AD` : truncated;
|
|
755
|
+
return /* @__PURE__ */ jsx9("div", { className: "lax-tool-body lax-tool-body--skill", children: /* @__PURE__ */ jsx9(
|
|
756
|
+
TruncatedContent,
|
|
757
|
+
{
|
|
758
|
+
text: bodyText,
|
|
759
|
+
mode: bodyMode,
|
|
760
|
+
maxLines: 12,
|
|
761
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
762
|
+
}
|
|
763
|
+
) });
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
// src/view/tools/webfetch/WebFetchToolBody.tsx
|
|
767
|
+
import { jsx as jsx10 } from "react/jsx-runtime";
|
|
768
|
+
var RECEIVED_RE = /Received\s+.+/i;
|
|
769
|
+
var MAX_BODY_LINES2 = 15;
|
|
770
|
+
function buildWebFetchBody(result) {
|
|
771
|
+
const d = asDisplayRecord(result?.display);
|
|
772
|
+
if (d?.content_length != null) {
|
|
773
|
+
const parts = [`Received ${d.content_length} bytes`];
|
|
774
|
+
if (d.duration_ms != null) parts.push(`in ${d.duration_ms}ms`);
|
|
775
|
+
if (d.from_cache) parts.push("(cached)");
|
|
776
|
+
return parts.join(" ");
|
|
777
|
+
}
|
|
778
|
+
const text = result?.summary?.trim() ?? "";
|
|
779
|
+
if (!text) return "(done)";
|
|
780
|
+
const match = text.match(RECEIVED_RE);
|
|
781
|
+
if (match) {
|
|
782
|
+
const line = match[0].split("\n", 1)[0] ?? match[0];
|
|
783
|
+
return text.length <= 400 ? text : `${line}
|
|
784
|
+
\u2026`;
|
|
785
|
+
}
|
|
786
|
+
const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES2);
|
|
787
|
+
return was ? `${truncated}
|
|
788
|
+
\u2026 \u5DF2\u622A\u65AD` : truncated;
|
|
789
|
+
}
|
|
790
|
+
function WebFetchToolBody({
|
|
791
|
+
result,
|
|
792
|
+
bodyMode,
|
|
793
|
+
onBodyModeChange
|
|
794
|
+
}) {
|
|
795
|
+
if (result?.error) {
|
|
796
|
+
return /* @__PURE__ */ jsx10("div", { className: "lax-tool-body lax-tool-body--webfetch", children: /* @__PURE__ */ jsx10("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx10("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
797
|
+
}
|
|
798
|
+
const bodyText = buildWebFetchBody(result);
|
|
799
|
+
return /* @__PURE__ */ jsx10("div", { className: "lax-tool-body lax-tool-body--webfetch", children: /* @__PURE__ */ jsx10(
|
|
800
|
+
TruncatedContent,
|
|
801
|
+
{
|
|
802
|
+
text: bodyText,
|
|
803
|
+
mode: bodyMode,
|
|
804
|
+
maxLines: 12,
|
|
805
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
806
|
+
}
|
|
807
|
+
) });
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
// src/view/tools/websearch/WebSearchToolBody.tsx
|
|
811
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
812
|
+
var MAX_BODY_LINES3 = 15;
|
|
813
|
+
function buildWebSearchBody(result) {
|
|
814
|
+
const d = asDisplayRecord(result?.display);
|
|
815
|
+
if (d?.total_hits != null) {
|
|
816
|
+
const engine = strField(d, "search_engine") || "search";
|
|
817
|
+
return `Web search (${engine}): ${d.total_hits} results`;
|
|
818
|
+
}
|
|
819
|
+
const text = result?.summary?.trim() ?? "";
|
|
820
|
+
if (!text) return "(done)";
|
|
821
|
+
const first = text.split("\n", 1)[0]?.trim() ?? "";
|
|
822
|
+
if (/^(web search|did |found )/i.test(first)) {
|
|
823
|
+
return text.length < 300 ? text : `${first}
|
|
824
|
+
\u2026`;
|
|
825
|
+
}
|
|
826
|
+
const { text: truncated, truncated: was } = truncateLines(text, MAX_BODY_LINES3);
|
|
827
|
+
return was ? `${truncated}
|
|
828
|
+
\u2026 \u5DF2\u622A\u65AD` : truncated;
|
|
829
|
+
}
|
|
830
|
+
function WebSearchToolBody({
|
|
831
|
+
result,
|
|
832
|
+
bodyMode,
|
|
833
|
+
onBodyModeChange
|
|
834
|
+
}) {
|
|
835
|
+
if (result?.error) {
|
|
836
|
+
return /* @__PURE__ */ jsx11("div", { className: "lax-tool-body lax-tool-body--websearch", children: /* @__PURE__ */ jsx11("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx11("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
837
|
+
}
|
|
838
|
+
const bodyText = buildWebSearchBody(result);
|
|
839
|
+
return /* @__PURE__ */ jsx11("div", { className: "lax-tool-body lax-tool-body--websearch", children: /* @__PURE__ */ jsx11(
|
|
840
|
+
TruncatedContent,
|
|
841
|
+
{
|
|
842
|
+
text: bodyText,
|
|
843
|
+
mode: bodyMode,
|
|
844
|
+
maxLines: 12,
|
|
845
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
846
|
+
}
|
|
847
|
+
) });
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
// src/view/tools/write/WriteToolBody.tsx
|
|
851
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
852
|
+
function buildWriteBodyText(input, display, summary) {
|
|
853
|
+
const d = asDisplayRecord(display);
|
|
854
|
+
const inp = asInputRecord(input);
|
|
855
|
+
const content = strField(inp, "content");
|
|
856
|
+
const path = displayPath(
|
|
857
|
+
strField(d ?? {}, "file_path") || strField(inp, "file_path")
|
|
858
|
+
);
|
|
859
|
+
const fileType = strField(d ?? {}, "type");
|
|
860
|
+
const original = d?.original_file;
|
|
861
|
+
if (fileType === "update" && original != null && content) {
|
|
862
|
+
return {
|
|
863
|
+
kind: "diff",
|
|
864
|
+
text: formatDiffFromStrings(String(original), content)
|
|
865
|
+
};
|
|
866
|
+
}
|
|
867
|
+
const diffText = strField(d ?? {}, "diff");
|
|
868
|
+
if (diffText) {
|
|
869
|
+
return { kind: "diff", text: diffText };
|
|
870
|
+
}
|
|
871
|
+
const numLines = typeof d?.num_lines === "number" ? d.num_lines : countLines(content);
|
|
872
|
+
if (numLines === 0 && !content.trim()) {
|
|
873
|
+
const trimmed = summary.trim();
|
|
874
|
+
return { kind: "text", text: trimmed || "(No content)" };
|
|
875
|
+
}
|
|
876
|
+
const lines = content.split("\n");
|
|
877
|
+
const preview = lines.slice(0, WRITE_PREVIEW_LINES).join("\n");
|
|
878
|
+
const remaining = numLines - WRITE_PREVIEW_LINES;
|
|
879
|
+
const header = `Wrote ${numLines} lines to ${path || "file"}`;
|
|
880
|
+
const body = remaining > 0 ? `${header}
|
|
881
|
+
${preview}
|
|
882
|
+
\u2026 +${remaining} lines` : `${header}
|
|
883
|
+
${preview}`;
|
|
884
|
+
return { kind: "preview", text: body };
|
|
885
|
+
}
|
|
886
|
+
function WriteToolBody({
|
|
887
|
+
input,
|
|
888
|
+
result,
|
|
889
|
+
bodyMode,
|
|
890
|
+
onBodyModeChange
|
|
891
|
+
}) {
|
|
892
|
+
if (result?.error) {
|
|
893
|
+
return /* @__PURE__ */ jsx12("div", { className: "lax-tool-body lax-tool-body--write", children: /* @__PURE__ */ jsx12("div", { className: "lax-tool-body__block", "data-variant": "error", children: /* @__PURE__ */ jsx12("pre", { className: "lax-tool-body__text", children: result.error.message }) }) });
|
|
894
|
+
}
|
|
895
|
+
const body = buildWriteBodyText(
|
|
896
|
+
input,
|
|
897
|
+
result?.display,
|
|
898
|
+
result?.summary ?? ""
|
|
899
|
+
);
|
|
900
|
+
if (body.kind === "diff") {
|
|
901
|
+
return /* @__PURE__ */ jsx12("div", { className: "lax-tool-body lax-tool-body--write", children: /* @__PURE__ */ jsx12(
|
|
902
|
+
DiffView,
|
|
903
|
+
{
|
|
904
|
+
diff: body.text,
|
|
905
|
+
mode: bodyMode,
|
|
906
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
907
|
+
}
|
|
908
|
+
) });
|
|
909
|
+
}
|
|
910
|
+
return /* @__PURE__ */ jsx12("div", { className: "lax-tool-body lax-tool-body--write", children: /* @__PURE__ */ jsx12(
|
|
911
|
+
TruncatedContent,
|
|
912
|
+
{
|
|
913
|
+
text: body.text,
|
|
914
|
+
mode: bodyMode,
|
|
915
|
+
maxLines: WRITE_PREVIEW_LINES + 1,
|
|
916
|
+
onExpand: () => onBodyModeChange?.("full")
|
|
917
|
+
}
|
|
918
|
+
) });
|
|
919
|
+
}
|
|
920
|
+
|
|
921
|
+
// src/view/tools/registry.ts
|
|
922
|
+
var ToolDisplayRegistry = class {
|
|
923
|
+
map = /* @__PURE__ */ new Map();
|
|
924
|
+
register(toolName, body) {
|
|
925
|
+
this.map.set(toolName, body);
|
|
926
|
+
return this;
|
|
927
|
+
}
|
|
928
|
+
resolve(toolName) {
|
|
929
|
+
return this.map.get(toolName);
|
|
930
|
+
}
|
|
931
|
+
static default() {
|
|
932
|
+
return createDefaultToolRegistry();
|
|
933
|
+
}
|
|
934
|
+
};
|
|
935
|
+
function createDefaultToolRegistry() {
|
|
936
|
+
return new ToolDisplayRegistry().register(Read, ReadToolBody).register(Grep, GrepToolBody).register(Glob, GlobToolBody).register(Edit, EditToolBody).register(Write, WriteToolBody).register(Bash, BashToolBody).register(Agent, AgentToolBody).register(Skill, SkillToolBody).register(AskUserQuestion, AskUserQuestionToolBody).register(WebSearch, WebSearchToolBody).register(WebFetch, WebFetchToolBody);
|
|
937
|
+
}
|
|
938
|
+
|
|
939
|
+
export {
|
|
940
|
+
Read,
|
|
941
|
+
Write,
|
|
942
|
+
Edit,
|
|
943
|
+
Glob,
|
|
944
|
+
Grep,
|
|
945
|
+
Bash,
|
|
946
|
+
Skill,
|
|
947
|
+
Agent,
|
|
948
|
+
AskUserQuestion,
|
|
949
|
+
WebSearch,
|
|
950
|
+
WebFetch,
|
|
951
|
+
SILENT_TASK_TOOL_NAMES,
|
|
952
|
+
INTERNAL_TOOL_NAMES,
|
|
953
|
+
formatAgentTitle,
|
|
954
|
+
AgentToolBody,
|
|
955
|
+
asDisplayRecord,
|
|
956
|
+
asInputRecord,
|
|
957
|
+
strField,
|
|
958
|
+
numField,
|
|
959
|
+
AskUserQuestionToolBody,
|
|
960
|
+
BashToolBody,
|
|
961
|
+
EditToolBody,
|
|
962
|
+
GlobToolBody,
|
|
963
|
+
GrepToolBody,
|
|
964
|
+
ReadToolBody,
|
|
965
|
+
SkillToolBody,
|
|
966
|
+
WebFetchToolBody,
|
|
967
|
+
WebSearchToolBody,
|
|
968
|
+
WriteToolBody,
|
|
969
|
+
ToolDisplayRegistry,
|
|
970
|
+
createDefaultToolRegistry
|
|
971
|
+
};
|
|
972
|
+
//# sourceMappingURL=chunk-MHK53ZHC.js.map
|