@agents24/chat-react 0.1.2 → 0.1.3
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 +7 -3
- package/dist/index.cjs +227 -125
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +100 -22
- package/dist/index.d.ts +100 -22
- package/dist/index.js +218 -122
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,7 +13,8 @@ var titleFromMessage = (text, files = []) => {
|
|
|
13
13
|
return base.replace(/\s+/g, " ").slice(0, 48);
|
|
14
14
|
};
|
|
15
15
|
var threadActivityDate = (thread) => String(thread.updated_at || thread.last_activity_at || thread.created_at || (/* @__PURE__ */ new Date()).toISOString());
|
|
16
|
-
var
|
|
16
|
+
var assistantTextFromResponseBlocks = (blocks) => (blocks || []).filter((block) => block.kind === "assistant_text" && typeof block.text === "string").map((block) => String(block.text)).join("\n\n").trim();
|
|
17
|
+
var assistantTextFromParts = (parts) => (parts || []).filter((part) => part.kind === "text").map((part) => part.text).join("\n\n").trim();
|
|
17
18
|
var textFromFinalOutput = (value) => {
|
|
18
19
|
if (typeof value === "string") return value;
|
|
19
20
|
if (!value || typeof value !== "object") return "";
|
|
@@ -58,95 +59,126 @@ var assistantTextFromEvents = (events) => {
|
|
|
58
59
|
if (typeof assistantText === "string" && assistantText.trim()) return assistantText;
|
|
59
60
|
return textFromFinalOutput(latestEventPayloadValue(events, "final_output"));
|
|
60
61
|
};
|
|
61
|
-
var
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : null;
|
|
63
|
+
var optionalString = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
64
|
+
var toolStateFromStatus = (status) => {
|
|
65
|
+
const normalized = String(status || "").trim().toLowerCase();
|
|
66
|
+
if (["failed", "error"].includes(normalized)) return "output-error";
|
|
67
|
+
if (["cancelled", "canceled"].includes(normalized)) return "cancelled";
|
|
68
|
+
if (["complete", "completed", "done", "success"].includes(normalized)) return "output-available";
|
|
69
|
+
if (["running", "active", "pending", "streaming"].includes(normalized)) return "input-available";
|
|
70
|
+
return "input-available";
|
|
65
71
|
};
|
|
66
|
-
var
|
|
67
|
-
var
|
|
68
|
-
var
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
return name ? humanize(name) : actionLabels[toolActionKey(tool)];
|
|
92
|
-
};
|
|
93
|
-
var toolDetail = (tool) => {
|
|
94
|
-
const summary = String(tool.summary || "").trim();
|
|
95
|
-
const detail = String(tool.detail || "").trim();
|
|
96
|
-
return summary || detail || void 0;
|
|
97
|
-
};
|
|
98
|
-
var summarizeToolGroup = (tools) => {
|
|
99
|
-
if (tools.length === 1) return tools[0].title;
|
|
100
|
-
const counts = /* @__PURE__ */ new Map();
|
|
101
|
-
tools.forEach((tool) => counts.set(tool.actionKey, (counts.get(tool.actionKey) || 0) + 1));
|
|
102
|
-
return Array.from(counts.entries()).map(([key, count]) => `${actionLabels[key]} ${count}`).join(", ");
|
|
103
|
-
};
|
|
104
|
-
var toolGroupStatus = (tools) => {
|
|
105
|
-
if (tools.some((tool) => tool.status === "error")) return "error";
|
|
106
|
-
if (tools.some((tool) => tool.status === "running")) return "running";
|
|
107
|
-
return "done";
|
|
72
|
+
var toolNameFromRecord = (tool) => String(tool.toolName || tool.tool_name || tool.name || tool.slug || tool.action || "tool").trim() || "tool";
|
|
73
|
+
var toolCallIdFromRecords = (block, tool) => optionalString(tool.toolCallId) || optionalString(tool.tool_call_id) || optionalString(block.toolCallId) || optionalString(block.tool_call_id) || optionalString(block.id) || null;
|
|
74
|
+
var presentationFromTool = (tool) => {
|
|
75
|
+
const presentation = asRecord(tool.presentation);
|
|
76
|
+
const outputView = asRecord(tool.outputView) || asRecord(tool.output_view);
|
|
77
|
+
const next = presentation ? { ...presentation } : {};
|
|
78
|
+
[
|
|
79
|
+
"title",
|
|
80
|
+
"activity",
|
|
81
|
+
"detail",
|
|
82
|
+
"category",
|
|
83
|
+
"groupKey",
|
|
84
|
+
"groupLabel",
|
|
85
|
+
"showOutput",
|
|
86
|
+
"outputView"
|
|
87
|
+
].forEach((key) => {
|
|
88
|
+
if (tool[key] !== void 0) {
|
|
89
|
+
next[key] = tool[key];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
if (tool.group_key !== void 0) next.group_key = tool.group_key;
|
|
93
|
+
if (tool.group_label !== void 0) next.group_label = tool.group_label;
|
|
94
|
+
if (tool.show_output !== void 0) next.show_output = tool.show_output;
|
|
95
|
+
if (outputView && next.outputView === void 0) next.outputView = outputView;
|
|
96
|
+
return Object.keys(next).length > 0 ? next : null;
|
|
108
97
|
};
|
|
109
|
-
var
|
|
110
|
-
const tool = block.tool || {};
|
|
111
|
-
const
|
|
98
|
+
var createToolPart = (block, index) => {
|
|
99
|
+
const tool = asRecord(block.tool) || {};
|
|
100
|
+
const toolName = toolNameFromRecord(tool);
|
|
101
|
+
const errorText = optionalString(tool.errorText) || optionalString(tool.error) || optionalString(block.error) || null;
|
|
112
102
|
return {
|
|
113
103
|
id: String(block.id || `${block.kind || "tool"}-${index}`),
|
|
104
|
+
type: `tool-${toolName}`,
|
|
114
105
|
kind: "tool",
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
106
|
+
toolName,
|
|
107
|
+
toolCallId: toolCallIdFromRecords(block, tool),
|
|
108
|
+
state: toolStateFromStatus(block.status),
|
|
109
|
+
input: tool.input ?? block.input,
|
|
110
|
+
output: tool.output ?? block.output,
|
|
111
|
+
errorText,
|
|
112
|
+
presentation: presentationFromTool(tool),
|
|
113
|
+
raw: block
|
|
120
114
|
};
|
|
121
115
|
};
|
|
122
|
-
var
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
tools: pendingTools
|
|
133
|
-
});
|
|
134
|
-
pendingTools = [];
|
|
135
|
-
};
|
|
116
|
+
var createDataPart = (block, index, name = String(block.kind || "data")) => ({
|
|
117
|
+
id: String(block.id || `${name}-${index}`),
|
|
118
|
+
type: "data",
|
|
119
|
+
kind: "data",
|
|
120
|
+
name,
|
|
121
|
+
data: block,
|
|
122
|
+
raw: block
|
|
123
|
+
});
|
|
124
|
+
var partsFromResponseBlocks = (blocks, fallbackText) => {
|
|
125
|
+
const parts = [];
|
|
136
126
|
(blocks || []).forEach((block, index) => {
|
|
137
127
|
const id = String(block.id || `${block.kind || "block"}-${index}`);
|
|
138
128
|
if (block.kind === "assistant_text" && typeof block.text === "string") {
|
|
139
|
-
|
|
140
|
-
|
|
129
|
+
parts.push({ id, type: "text", kind: "text", text: String(block.text), raw: block });
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (block.kind === "tool_call") {
|
|
133
|
+
parts.push(createToolPart(block, index));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (block.kind === "ui_blocks") {
|
|
137
|
+
parts.push({
|
|
138
|
+
id,
|
|
139
|
+
type: "ui-blocks",
|
|
140
|
+
kind: "ui-blocks",
|
|
141
|
+
state: toolStateFromStatus(block.status),
|
|
142
|
+
toolCallId: optionalString(block.toolCallId) || optionalString(block.tool_call_id) || null,
|
|
143
|
+
contractVersion: optionalString(block.contractVersion) || optionalString(block.contract_version) || null,
|
|
144
|
+
bundle: asRecord(block.bundle),
|
|
145
|
+
errorText: optionalString(block.error) || null,
|
|
146
|
+
raw: block
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (block.kind === "reasoning_note") {
|
|
151
|
+
parts.push({
|
|
152
|
+
id,
|
|
153
|
+
type: "reasoning",
|
|
154
|
+
kind: "reasoning",
|
|
155
|
+
label: optionalString(block.label) || null,
|
|
156
|
+
text: optionalString(block.text) || optionalString(block.summary) || null,
|
|
157
|
+
status: optionalString(block.status) || null,
|
|
158
|
+
raw: block
|
|
159
|
+
});
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
if (block.kind === "approval_request") {
|
|
163
|
+
parts.push({ id, type: "approval", kind: "approval", raw: block });
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
if (block.kind === "error") {
|
|
167
|
+
parts.push({
|
|
168
|
+
id,
|
|
169
|
+
type: "error",
|
|
170
|
+
kind: "error",
|
|
171
|
+
errorText: optionalString(block.error) || optionalString(block.message) || "Error",
|
|
172
|
+
raw: block
|
|
173
|
+
});
|
|
141
174
|
return;
|
|
142
175
|
}
|
|
143
|
-
|
|
176
|
+
parts.push(createDataPart(block, index));
|
|
144
177
|
});
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
mapped.push({ id: "assistant-fallback-text", kind: "text", content: fallbackText });
|
|
178
|
+
if (!parts.some((part) => part.kind === "text") && fallbackText?.trim()) {
|
|
179
|
+
parts.push({ id: "assistant-fallback-text", type: "text", kind: "text", text: fallbackText });
|
|
148
180
|
}
|
|
149
|
-
return
|
|
181
|
+
return parts;
|
|
150
182
|
};
|
|
151
183
|
var mergeReasoningSteps = (steps, options) => {
|
|
152
184
|
if (!steps?.length) return [];
|
|
@@ -164,21 +196,20 @@ var mergeReasoningSteps = (steps, options) => {
|
|
|
164
196
|
});
|
|
165
197
|
return merged;
|
|
166
198
|
};
|
|
167
|
-
var
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
const tool = block.tool || {};
|
|
199
|
+
var reasoningStepsFromParts = (parts) => (parts || []).map((block) => {
|
|
200
|
+
if (block.kind === "tool") {
|
|
201
|
+
const label = optionalString(block.presentation?.activity) || optionalString(block.presentation?.title) || block.toolName;
|
|
171
202
|
return {
|
|
172
|
-
label
|
|
173
|
-
status: block.
|
|
174
|
-
description:
|
|
203
|
+
label,
|
|
204
|
+
status: block.state === "input-available" || block.state === "input-streaming" ? "active" : "complete",
|
|
205
|
+
description: optionalString(block.presentation?.detail) || ""
|
|
175
206
|
};
|
|
176
207
|
}
|
|
177
|
-
if (kind === "
|
|
208
|
+
if (block.kind === "reasoning") {
|
|
178
209
|
return {
|
|
179
|
-
label:
|
|
210
|
+
label: block.label || "Reasoning",
|
|
180
211
|
status: block.status === "running" ? "active" : "complete",
|
|
181
|
-
description:
|
|
212
|
+
description: block.text || ""
|
|
182
213
|
};
|
|
183
214
|
}
|
|
184
215
|
return null;
|
|
@@ -197,19 +228,21 @@ var turnToMessages = (turn, activeRunId) => {
|
|
|
197
228
|
role: "user",
|
|
198
229
|
content: userContent,
|
|
199
230
|
createdAt,
|
|
231
|
+
parts: userContent ? [{ id: `${baseId}-user-text`, type: "text", kind: "text", text: userContent }] : [],
|
|
200
232
|
attachments
|
|
201
233
|
});
|
|
202
234
|
}
|
|
203
|
-
const assistantText = turn.assistant_output_text ||
|
|
235
|
+
const assistantText = turn.assistant_output_text || assistantTextFromResponseBlocks(responseBlocks) || assistantTextFromEvents(turn.run_events) || textFromFinalOutput(turn.final_output);
|
|
204
236
|
if (assistantText || responseBlocks.length > 0 || isRunning) {
|
|
237
|
+
const parts = partsFromResponseBlocks(responseBlocks, assistantText);
|
|
205
238
|
messages.push({
|
|
206
239
|
id: `${baseId}-assistant`,
|
|
207
240
|
role: "assistant",
|
|
208
241
|
runId: turn.run_id || null,
|
|
209
|
-
content: assistantText,
|
|
242
|
+
content: assistantText || assistantTextFromParts(parts),
|
|
210
243
|
createdAt: turn.completed_at ? new Date(turn.completed_at) : createdAt,
|
|
211
|
-
|
|
212
|
-
reasoningSteps: mergeReasoningSteps(
|
|
244
|
+
parts,
|
|
245
|
+
reasoningSteps: mergeReasoningSteps(reasoningStepsFromParts(parts), { finalize: !isRunning }),
|
|
213
246
|
isFinal: !isRunning
|
|
214
247
|
});
|
|
215
248
|
}
|
|
@@ -423,7 +456,7 @@ function useAgents24ChatController({
|
|
|
423
456
|
createdAt: /* @__PURE__ */ new Date(),
|
|
424
457
|
reasoningSteps: input.reasoning,
|
|
425
458
|
isFinal: false,
|
|
426
|
-
|
|
459
|
+
parts: input.parts || []
|
|
427
460
|
});
|
|
428
461
|
messagesRef.current = next2;
|
|
429
462
|
return next2;
|
|
@@ -435,7 +468,7 @@ function useAgents24ChatController({
|
|
|
435
468
|
content: input.content,
|
|
436
469
|
reasoningSteps: input.reasoning,
|
|
437
470
|
isFinal: false,
|
|
438
|
-
|
|
471
|
+
parts: input.parts ?? next[index].parts
|
|
439
472
|
};
|
|
440
473
|
messagesRef.current = next;
|
|
441
474
|
return next;
|
|
@@ -451,7 +484,7 @@ function useAgents24ChatController({
|
|
|
451
484
|
(message) => input.messageId && message.id === input.messageId || input.runId && message.role === "assistant" && message.runId === input.runId
|
|
452
485
|
);
|
|
453
486
|
const existing = existingIndex >= 0 ? input.baseMessages[existingIndex] : void 0;
|
|
454
|
-
const
|
|
487
|
+
const parts = input.parts || existing?.parts || partsFromResponseBlocks(void 0, content);
|
|
455
488
|
const assistant = {
|
|
456
489
|
id: existing?.id || input.messageId || createId(),
|
|
457
490
|
role: "assistant",
|
|
@@ -459,13 +492,7 @@ function useAgents24ChatController({
|
|
|
459
492
|
content,
|
|
460
493
|
createdAt: /* @__PURE__ */ new Date(),
|
|
461
494
|
isFinal: true,
|
|
462
|
-
|
|
463
|
-
if (block.kind === "tool") return { ...block, status: input.error ? "error" : "done" };
|
|
464
|
-
if (block.kind === "tool_group") {
|
|
465
|
-
return { ...block, status: input.error ? "error" : "done", tools: block.tools.map((tool) => ({ ...tool, status: input.error ? "error" : "done" })) };
|
|
466
|
-
}
|
|
467
|
-
return block;
|
|
468
|
-
}),
|
|
495
|
+
parts,
|
|
469
496
|
reasoningSteps: mergeReasoningSteps(input.reasoning, { finalize: true }),
|
|
470
497
|
thinkingDurationMs: input.thinkingDurationMs
|
|
471
498
|
};
|
|
@@ -500,7 +527,11 @@ function useAgents24ChatController({
|
|
|
500
527
|
setIsLoadingOlder(false);
|
|
501
528
|
isLoadingOlderRef.current = false;
|
|
502
529
|
try {
|
|
503
|
-
const detail = await transport.getThread({
|
|
530
|
+
const detail = await transport.getThread({
|
|
531
|
+
threadId,
|
|
532
|
+
limit: pageSize,
|
|
533
|
+
includeRunEvents: false
|
|
534
|
+
});
|
|
504
535
|
if (activeThreadIdRef.current !== threadId || seq !== requestSeqRef.current) return;
|
|
505
536
|
const nextMessages = threadDetailToMessages(detail);
|
|
506
537
|
const paging = threadPaging(detail);
|
|
@@ -532,7 +563,12 @@ function useAgents24ChatController({
|
|
|
532
563
|
isLoadingOlderRef.current = true;
|
|
533
564
|
setIsLoadingOlder(true);
|
|
534
565
|
try {
|
|
535
|
-
const detail = await transport.getThread({
|
|
566
|
+
const detail = await transport.getThread({
|
|
567
|
+
threadId,
|
|
568
|
+
limit: pageSize,
|
|
569
|
+
beforeTurnIndex,
|
|
570
|
+
includeRunEvents: false
|
|
571
|
+
});
|
|
536
572
|
if (activeThreadIdRef.current !== threadId) return;
|
|
537
573
|
const older = threadDetailToMessages(detail);
|
|
538
574
|
const paging = threadPaging(detail);
|
|
@@ -556,16 +592,17 @@ function useAgents24ChatController({
|
|
|
556
592
|
if (event.run_id) activeRunIdRef.current = event.run_id;
|
|
557
593
|
setContextStatus((current) => mergeContextWindow(current, payload.context_window));
|
|
558
594
|
if (responseBlocks) {
|
|
559
|
-
const blockText = String(payload.assistant_output_text || "") ||
|
|
595
|
+
const blockText = String(payload.assistant_output_text || "") || assistantTextFromResponseBlocks(responseBlocks) || streamingContentRef.current;
|
|
560
596
|
if (blockText) setStreamingText(blockText);
|
|
561
|
-
const
|
|
597
|
+
const parts = partsFromResponseBlocks(responseBlocks, blockText);
|
|
598
|
+
const reasoning = mergeReasoningSteps([...reasoningRef.current, ...reasoningStepsFromParts(parts)]);
|
|
562
599
|
setReasoningSteps(reasoning);
|
|
563
600
|
setLiveAssistantMessage({
|
|
564
601
|
messageId: assistantMessageId,
|
|
565
602
|
runId: event.run_id || activeRunIdRef.current,
|
|
566
603
|
content: blockText,
|
|
567
604
|
reasoning,
|
|
568
|
-
|
|
605
|
+
parts,
|
|
569
606
|
baseMessages
|
|
570
607
|
});
|
|
571
608
|
}
|
|
@@ -595,7 +632,7 @@ function useAgents24ChatController({
|
|
|
595
632
|
thinkingDurationMs: Date.now() - startedAt,
|
|
596
633
|
messageId: assistantMessageId,
|
|
597
634
|
runId: event.run_id || activeRunIdRef.current,
|
|
598
|
-
|
|
635
|
+
parts: responseBlocks ? partsFromResponseBlocks(responseBlocks, finalText) : void 0,
|
|
599
636
|
error: isFailed ? String(payload.message || payload.error || event.diagnostics?.[0]?.message || onStreamErrorMessage?.(event) || "The chat run failed.") : void 0
|
|
600
637
|
});
|
|
601
638
|
},
|
|
@@ -622,6 +659,7 @@ function useAgents24ChatController({
|
|
|
622
659
|
role: "user",
|
|
623
660
|
content: input.message.text,
|
|
624
661
|
createdAt: /* @__PURE__ */ new Date(),
|
|
662
|
+
parts: input.message.text ? [{ id: createId(), type: "text", kind: "text", text: input.message.text }] : [],
|
|
625
663
|
attachments: input.message.files
|
|
626
664
|
};
|
|
627
665
|
baseMessages = [...messagesRef.current, userMessage];
|
|
@@ -633,6 +671,7 @@ function useAgents24ChatController({
|
|
|
633
671
|
content: "",
|
|
634
672
|
createdAt: /* @__PURE__ */ new Date(),
|
|
635
673
|
isFinal: false,
|
|
674
|
+
parts: [],
|
|
636
675
|
reasoningSteps: []
|
|
637
676
|
};
|
|
638
677
|
const liveMessages = [...baseMessages, assistantMessage];
|
|
@@ -843,6 +882,7 @@ function useAgents24ChatController({
|
|
|
843
882
|
createdAt: /* @__PURE__ */ new Date(),
|
|
844
883
|
isFinal: Boolean(input.isFinal),
|
|
845
884
|
isVoice: input.role === "user",
|
|
885
|
+
parts: content ? [{ id: createId(), type: "text", kind: "text", text: content }] : [],
|
|
846
886
|
citations: input.citations,
|
|
847
887
|
reasoningSteps: input.reasoningSteps
|
|
848
888
|
};
|
|
@@ -906,6 +946,53 @@ function useAgents24ChatController({
|
|
|
906
946
|
]);
|
|
907
947
|
}
|
|
908
948
|
|
|
949
|
+
// src/renderers.tsx
|
|
950
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
951
|
+
var DefaultToolPart = ({ part }) => {
|
|
952
|
+
const label = typeof part.presentation?.activity === "string" ? part.presentation.activity : typeof part.presentation?.title === "string" ? part.presentation.title : part.toolName;
|
|
953
|
+
const detail = typeof part.presentation?.detail === "string" ? part.presentation.detail : part.errorText || part.state;
|
|
954
|
+
return /* @__PURE__ */ jsxs("div", { "data-agents24-tool-part": part.type, "data-state": part.state, children: [
|
|
955
|
+
/* @__PURE__ */ jsx("div", { children: label }),
|
|
956
|
+
detail ? /* @__PURE__ */ jsx("div", { children: detail }) : null
|
|
957
|
+
] });
|
|
958
|
+
};
|
|
959
|
+
var DefaultChatPart = ({
|
|
960
|
+
part,
|
|
961
|
+
message,
|
|
962
|
+
renderOptions
|
|
963
|
+
}) => {
|
|
964
|
+
if (renderOptions?.renderPart) {
|
|
965
|
+
return /* @__PURE__ */ jsx(Fragment, { children: renderOptions.renderPart(part, message) });
|
|
966
|
+
}
|
|
967
|
+
if (part.kind === "text") return /* @__PURE__ */ jsx(Fragment, { children: part.text });
|
|
968
|
+
if (part.kind === "tool") {
|
|
969
|
+
const ToolRenderer = renderOptions?.toolRenderers?.[part.type] || renderOptions?.fallbackToolRenderer || DefaultToolPart;
|
|
970
|
+
return /* @__PURE__ */ jsx(Fragment, { children: ToolRenderer({ part, message }) });
|
|
971
|
+
}
|
|
972
|
+
if (part.kind === "reasoning") {
|
|
973
|
+
return /* @__PURE__ */ jsx("div", { "data-agents24-reasoning-part": true, children: part.text || part.label });
|
|
974
|
+
}
|
|
975
|
+
if (part.kind === "ui-blocks") {
|
|
976
|
+
return /* @__PURE__ */ jsx("div", { "data-agents24-ui-blocks-part": true, "data-state": part.state });
|
|
977
|
+
}
|
|
978
|
+
if (part.kind === "approval") {
|
|
979
|
+
return /* @__PURE__ */ jsx("div", { "data-agents24-approval-part": true });
|
|
980
|
+
}
|
|
981
|
+
if (part.kind === "error") {
|
|
982
|
+
return /* @__PURE__ */ jsx("div", { "data-agents24-error-part": true, children: part.errorText });
|
|
983
|
+
}
|
|
984
|
+
return /* @__PURE__ */ jsx("div", { "data-agents24-data-part": part.name });
|
|
985
|
+
};
|
|
986
|
+
var renderChatPart = (part, message, renderOptions) => /* @__PURE__ */ jsx(
|
|
987
|
+
DefaultChatPart,
|
|
988
|
+
{
|
|
989
|
+
part,
|
|
990
|
+
message,
|
|
991
|
+
renderOptions
|
|
992
|
+
},
|
|
993
|
+
part.id
|
|
994
|
+
);
|
|
995
|
+
|
|
909
996
|
// src/sse.ts
|
|
910
997
|
var parseSseBlock = (block) => {
|
|
911
998
|
const data = block.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.replace(/^data:\s?/, "")).join("\n").trim();
|
|
@@ -1037,7 +1124,7 @@ import {
|
|
|
1037
1124
|
useRef as useRef2,
|
|
1038
1125
|
useState as useState2
|
|
1039
1126
|
} from "react";
|
|
1040
|
-
import { jsxs } from "react/jsx-runtime";
|
|
1127
|
+
import { jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1041
1128
|
var LATEST_EDGE_THRESHOLD_PX = 2;
|
|
1042
1129
|
var MIN_OLDER_PREFETCH_PX = 320;
|
|
1043
1130
|
var MAX_OLDER_PREFETCH_PX = 900;
|
|
@@ -1048,6 +1135,11 @@ var isAtTimelineLatestEdge = (element, isTopOrigin) => {
|
|
|
1048
1135
|
};
|
|
1049
1136
|
var shouldPrefetchOlder = (element) => Math.abs(element.scrollTop) + element.clientHeight >= element.scrollHeight - Math.min(MAX_OLDER_PREFETCH_PX, Math.max(MIN_OLDER_PREFETCH_PX, element.clientHeight * 0.75));
|
|
1050
1137
|
var getLatestScrollTop = (element, isTopOrigin) => isTopOrigin ? Math.max(0, element.scrollHeight - element.clientHeight) : 0;
|
|
1138
|
+
var shouldUseTopOriginTimeline = ({
|
|
1139
|
+
hasOlder,
|
|
1140
|
+
itemCount,
|
|
1141
|
+
topOriginMaxItems = 4
|
|
1142
|
+
}) => !hasOlder && itemCount > 0 && itemCount <= topOriginMaxItems;
|
|
1051
1143
|
function useLatestThreadViewport({
|
|
1052
1144
|
itemCount,
|
|
1053
1145
|
hasOlder,
|
|
@@ -1066,9 +1158,7 @@ function useLatestThreadViewport({
|
|
|
1066
1158
|
const programmaticScrollTimeoutRef = useRef2(null);
|
|
1067
1159
|
const activeStreamKeyRef = useRef2(null);
|
|
1068
1160
|
const [isAtLatest, setIsAtLatest] = useState2(true);
|
|
1069
|
-
const
|
|
1070
|
-
const topOriginCandidate = !hasOlder && itemCount > 0 && itemCount <= topOriginMaxItems;
|
|
1071
|
-
const isTopOrigin = topOriginCandidate && !topOriginCandidateOverflows;
|
|
1161
|
+
const isTopOrigin = shouldUseTopOriginTimeline({ hasOlder, itemCount, topOriginMaxItems });
|
|
1072
1162
|
const markProgrammaticScroll = useCallback2(() => {
|
|
1073
1163
|
programmaticScrollRef.current = true;
|
|
1074
1164
|
if (programmaticScrollTimeoutRef.current) clearTimeout(programmaticScrollTimeoutRef.current);
|
|
@@ -1095,11 +1185,6 @@ function useLatestThreadViewport({
|
|
|
1095
1185
|
const element = scrollContainerRef.current;
|
|
1096
1186
|
const preserve = olderPagePreserveRef.current;
|
|
1097
1187
|
if (!element) return;
|
|
1098
|
-
if (topOriginCandidate) {
|
|
1099
|
-
setTopOriginCandidateOverflows(isScrollable(element));
|
|
1100
|
-
} else if (topOriginCandidateOverflows) {
|
|
1101
|
-
setTopOriginCandidateOverflows(false);
|
|
1102
|
-
}
|
|
1103
1188
|
if (!preserve) {
|
|
1104
1189
|
setIsAtLatest(isAtTimelineLatestEdge(element, isTopOrigin));
|
|
1105
1190
|
return;
|
|
@@ -1110,7 +1195,7 @@ function useLatestThreadViewport({
|
|
|
1110
1195
|
olderPagePreserveRef.current = null;
|
|
1111
1196
|
olderPageRequestInFlightRef.current = false;
|
|
1112
1197
|
setIsAtLatest(isAtTimelineLatestEdge(element, isTopOrigin));
|
|
1113
|
-
}, [isTopOrigin, itemCount, markProgrammaticScroll
|
|
1198
|
+
}, [isTopOrigin, itemCount, markProgrammaticScroll]);
|
|
1114
1199
|
const handleScroll = useCallback2(
|
|
1115
1200
|
(event) => {
|
|
1116
1201
|
const element = event.currentTarget;
|
|
@@ -1171,18 +1256,23 @@ function useLatestThreadViewport({
|
|
|
1171
1256
|
return;
|
|
1172
1257
|
}
|
|
1173
1258
|
autoFollowLatestRef.current = true;
|
|
1259
|
+
if (isTopOrigin) {
|
|
1260
|
+
activeStreamKeyRef.current = key;
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1174
1263
|
const frame = requestAnimationFrame(scrollToLatest);
|
|
1175
1264
|
activeStreamKeyRef.current = key;
|
|
1176
1265
|
return () => cancelAnimationFrame(frame);
|
|
1177
|
-
}, [activeStreamKey, scrollToLatest]);
|
|
1266
|
+
}, [activeStreamKey, isTopOrigin, scrollToLatest]);
|
|
1178
1267
|
useLayoutEffect(() => {
|
|
1268
|
+
if (isTopOrigin) return;
|
|
1179
1269
|
if (!activeStreamKey || !shouldAutoFollow || !autoFollowLatestRef.current) return;
|
|
1180
1270
|
if (isLoadingOlder || olderPageRequestInFlightRef.current) return;
|
|
1181
1271
|
const frame = requestAnimationFrame(() => {
|
|
1182
1272
|
if (autoFollowLatestRef.current && !isLoadingOlder && !olderPageRequestInFlightRef.current) scrollToLatest();
|
|
1183
1273
|
});
|
|
1184
1274
|
return () => cancelAnimationFrame(frame);
|
|
1185
|
-
}, [activeStreamKey, isLoadingOlder, itemCount, scrollToLatest, shouldAutoFollow]);
|
|
1275
|
+
}, [activeStreamKey, isLoadingOlder, isTopOrigin, itemCount, scrollToLatest, shouldAutoFollow]);
|
|
1186
1276
|
return {
|
|
1187
1277
|
scrollContainerRef,
|
|
1188
1278
|
isAtLatest,
|
|
@@ -1212,7 +1302,7 @@ function LatestThreadViewport({
|
|
|
1212
1302
|
activeStreamKey
|
|
1213
1303
|
});
|
|
1214
1304
|
const timelineItems = useMemo2(() => viewport.isTopOrigin ? items : [...items].reverse(), [items, viewport.isTopOrigin]);
|
|
1215
|
-
return /* @__PURE__ */
|
|
1305
|
+
return /* @__PURE__ */ jsxs2(
|
|
1216
1306
|
"div",
|
|
1217
1307
|
{
|
|
1218
1308
|
ref: viewport.scrollContainerRef,
|
|
@@ -1230,10 +1320,13 @@ function LatestThreadViewport({
|
|
|
1230
1320
|
}
|
|
1231
1321
|
export {
|
|
1232
1322
|
DEFAULT_THREAD_PAGE_SIZE,
|
|
1323
|
+
DefaultChatPart,
|
|
1324
|
+
DefaultToolPart,
|
|
1233
1325
|
LatestThreadViewport,
|
|
1234
1326
|
activeRunIdFromThread,
|
|
1235
1327
|
activeRunIdFromThreadDetail,
|
|
1236
|
-
|
|
1328
|
+
assistantTextFromParts,
|
|
1329
|
+
assistantTextFromResponseBlocks,
|
|
1237
1330
|
consumeSseResponse,
|
|
1238
1331
|
createChatId,
|
|
1239
1332
|
createFetchChatTransport,
|
|
@@ -1246,14 +1339,17 @@ export {
|
|
|
1246
1339
|
latestContextWindowFromThread,
|
|
1247
1340
|
mergeReasoningSteps,
|
|
1248
1341
|
parseSseBlock,
|
|
1249
|
-
|
|
1250
|
-
|
|
1342
|
+
partsFromResponseBlocks,
|
|
1343
|
+
reasoningStepsFromParts,
|
|
1344
|
+
renderChatPart,
|
|
1251
1345
|
shouldPrefetchOlder,
|
|
1346
|
+
shouldUseTopOriginTimeline,
|
|
1252
1347
|
textFromFinalOutput,
|
|
1253
1348
|
threadActivityDate,
|
|
1254
1349
|
threadDetailToMessages,
|
|
1255
1350
|
threadPaging,
|
|
1256
1351
|
titleFromMessage,
|
|
1352
|
+
toolStateFromStatus,
|
|
1257
1353
|
useAgents24ChatController,
|
|
1258
1354
|
useLatestThreadViewport
|
|
1259
1355
|
};
|