@emblemvault/hustle-react 1.3.0 → 1.4.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/browser/hustle-react.js +101 -2
- package/dist/browser/hustle-react.js.map +1 -1
- package/dist/components/index.cjs +101 -2
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.js +101 -2
- package/dist/components/index.js.map +1 -1
- package/dist/index.cjs +101 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +101 -2
- package/dist/index.js.map +1 -1
- package/dist/plugins/index.cjs +1 -1
- package/dist/plugins/index.cjs.map +1 -1
- package/dist/plugins/index.js +1 -1
- package/dist/plugins/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -2006,7 +2006,7 @@ var screenshotExecutor = async (args2) => {
|
|
|
2006
2006
|
if (!window.html2canvas) {
|
|
2007
2007
|
await new Promise((resolve, reject) => {
|
|
2008
2008
|
const script = document.createElement("script");
|
|
2009
|
-
script.src = "https://
|
|
2009
|
+
script.src = "https://cdn.jsdelivr.net/npm/html2canvas-pro@1.5.0/dist/html2canvas-pro.min.js";
|
|
2010
2010
|
script.onload = () => resolve();
|
|
2011
2011
|
script.onerror = () => reject(new Error("Failed to load html2canvas"));
|
|
2012
2012
|
document.head.appendChild(script);
|
|
@@ -3715,7 +3715,11 @@ var styles = {
|
|
|
3715
3715
|
border: "none",
|
|
3716
3716
|
borderRadius: 0,
|
|
3717
3717
|
color: tokens.colors.textTertiary,
|
|
3718
|
-
flexShrink: 0
|
|
3718
|
+
flexShrink: 0,
|
|
3719
|
+
display: "flex",
|
|
3720
|
+
alignItems: "center",
|
|
3721
|
+
justifyContent: "center",
|
|
3722
|
+
cursor: "pointer"
|
|
3719
3723
|
},
|
|
3720
3724
|
inputWrapper: {
|
|
3721
3725
|
flex: 1
|
|
@@ -3937,6 +3941,7 @@ function HustleChat({
|
|
|
3937
3941
|
isLoading,
|
|
3938
3942
|
error: error2,
|
|
3939
3943
|
models,
|
|
3944
|
+
client,
|
|
3940
3945
|
chatStream,
|
|
3941
3946
|
uploadFile,
|
|
3942
3947
|
selectedModel,
|
|
@@ -3963,6 +3968,7 @@ function HustleChat({
|
|
|
3963
3968
|
const [showSettingsPanel, setShowSettingsPanel] = useState(false);
|
|
3964
3969
|
const messagesEndRef = useRef(null);
|
|
3965
3970
|
const fileInputRef = useRef(null);
|
|
3971
|
+
const messagesRef = useRef(messages);
|
|
3966
3972
|
useEffect(() => {
|
|
3967
3973
|
if (initialSystemPrompt && !systemPrompt) {
|
|
3968
3974
|
setSystemPrompt(initialSystemPrompt);
|
|
@@ -3971,6 +3977,9 @@ function HustleChat({
|
|
|
3971
3977
|
useEffect(() => {
|
|
3972
3978
|
messagesEndRef.current?.scrollIntoView({ behavior: "smooth" });
|
|
3973
3979
|
}, [messages]);
|
|
3980
|
+
useEffect(() => {
|
|
3981
|
+
messagesRef.current = messages;
|
|
3982
|
+
}, [messages]);
|
|
3974
3983
|
const handleFileSelect = useCallback(
|
|
3975
3984
|
async (e) => {
|
|
3976
3985
|
const files = e.target.files;
|
|
@@ -3992,6 +4001,96 @@ function HustleChat({
|
|
|
3992
4001
|
const removeAttachment = useCallback((index) => {
|
|
3993
4002
|
setAttachments((prev) => prev.filter((_, i) => i !== index));
|
|
3994
4003
|
}, []);
|
|
4004
|
+
const sendContinue = useCallback(async () => {
|
|
4005
|
+
if (isStreaming || !isReady) return;
|
|
4006
|
+
console.log("[AUTO_CONTINUE] Sending continue message...");
|
|
4007
|
+
const userMessage = {
|
|
4008
|
+
id: generateId(),
|
|
4009
|
+
role: "user",
|
|
4010
|
+
content: "continue"
|
|
4011
|
+
};
|
|
4012
|
+
setMessages((prev) => [...prev, userMessage]);
|
|
4013
|
+
onMessage?.(userMessage);
|
|
4014
|
+
const assistantMessage = {
|
|
4015
|
+
id: generateId(),
|
|
4016
|
+
role: "assistant",
|
|
4017
|
+
content: "",
|
|
4018
|
+
isStreaming: true,
|
|
4019
|
+
toolCalls: []
|
|
4020
|
+
};
|
|
4021
|
+
setMessages((prev) => [...prev, assistantMessage]);
|
|
4022
|
+
setIsStreaming(true);
|
|
4023
|
+
setCurrentToolCalls([]);
|
|
4024
|
+
try {
|
|
4025
|
+
const chatMessages = messagesRef.current.filter((m) => !m.isStreaming).map((m) => ({ role: m.role, content: m.content }));
|
|
4026
|
+
chatMessages.push({ role: "user", content: "continue" });
|
|
4027
|
+
const stream = chatStream({
|
|
4028
|
+
messages: chatMessages,
|
|
4029
|
+
processChunks: true
|
|
4030
|
+
});
|
|
4031
|
+
let fullContent = "";
|
|
4032
|
+
const toolCallsAccumulated = [];
|
|
4033
|
+
for await (const chunk of stream) {
|
|
4034
|
+
if (chunk.type === "text") {
|
|
4035
|
+
fullContent += chunk.value;
|
|
4036
|
+
setMessages(
|
|
4037
|
+
(prev) => prev.map(
|
|
4038
|
+
(m) => m.id === assistantMessage.id ? { ...m, content: fullContent } : m
|
|
4039
|
+
)
|
|
4040
|
+
);
|
|
4041
|
+
} else if (chunk.type === "tool_call") {
|
|
4042
|
+
const toolCall = chunk.value;
|
|
4043
|
+
toolCallsAccumulated.push(toolCall);
|
|
4044
|
+
setCurrentToolCalls([...toolCallsAccumulated]);
|
|
4045
|
+
setMessages(
|
|
4046
|
+
(prev) => prev.map(
|
|
4047
|
+
(m) => m.id === assistantMessage.id ? { ...m, toolCalls: [...toolCallsAccumulated] } : m
|
|
4048
|
+
)
|
|
4049
|
+
);
|
|
4050
|
+
onToolCall?.(toolCall);
|
|
4051
|
+
} else if (chunk.type === "error") {
|
|
4052
|
+
console.error("Stream error:", chunk.value);
|
|
4053
|
+
}
|
|
4054
|
+
}
|
|
4055
|
+
const processedResponse = await stream.response;
|
|
4056
|
+
const finalContent = processedResponse?.content || fullContent || "(No response)";
|
|
4057
|
+
setMessages(
|
|
4058
|
+
(prev) => prev.map(
|
|
4059
|
+
(m) => m.id === assistantMessage.id ? { ...m, isStreaming: false, content: finalContent } : m
|
|
4060
|
+
)
|
|
4061
|
+
);
|
|
4062
|
+
onResponse?.(finalContent);
|
|
4063
|
+
} catch (err) {
|
|
4064
|
+
console.error("Continue error:", err);
|
|
4065
|
+
setMessages(
|
|
4066
|
+
(prev) => prev.map(
|
|
4067
|
+
(m) => m.id === assistantMessage.id ? { ...m, isStreaming: false, content: `Error: ${err instanceof Error ? err.message : "Unknown error"}` } : m
|
|
4068
|
+
)
|
|
4069
|
+
);
|
|
4070
|
+
} finally {
|
|
4071
|
+
setIsStreaming(false);
|
|
4072
|
+
setCurrentToolCalls([]);
|
|
4073
|
+
}
|
|
4074
|
+
}, [isStreaming, isReady, chatStream, onMessage, onToolCall, onResponse]);
|
|
4075
|
+
useEffect(() => {
|
|
4076
|
+
if (!client) return;
|
|
4077
|
+
const unsubMaxTools = client.on("max_tools_reached", (event) => {
|
|
4078
|
+
console.log(`[AUTO_CONTINUE] Max tools reached (${event.toolsExecuted}/${event.maxSteps}), auto-continuing...`);
|
|
4079
|
+
setTimeout(() => {
|
|
4080
|
+
sendContinue();
|
|
4081
|
+
}, 100);
|
|
4082
|
+
});
|
|
4083
|
+
const unsubTimeout = client.on("timeout", (event) => {
|
|
4084
|
+
console.log(`[AUTO_CONTINUE] Timeout: ${event.message}, auto-continuing...`);
|
|
4085
|
+
setTimeout(() => {
|
|
4086
|
+
sendContinue();
|
|
4087
|
+
}, 100);
|
|
4088
|
+
});
|
|
4089
|
+
return () => {
|
|
4090
|
+
unsubMaxTools();
|
|
4091
|
+
unsubTimeout();
|
|
4092
|
+
};
|
|
4093
|
+
}, [client, sendContinue]);
|
|
3995
4094
|
const sendMessage = useCallback(async () => {
|
|
3996
4095
|
const content = inputValue.trim();
|
|
3997
4096
|
if (!content || isStreaming || !isReady) return;
|