@emblemvault/hustle-react 1.4.1 → 1.4.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/dist/browser/hustle-react.js +140 -7
- package/dist/browser/hustle-react.js.map +1 -1
- package/dist/components/index.cjs +140 -6
- package/dist/components/index.cjs.map +1 -1
- package/dist/components/index.d.cts +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +140 -6
- package/dist/components/index.js.map +1 -1
- package/dist/hooks/index.d.cts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/{hustle-S48t4lTZ.d.cts → hustle-C0Ltl5k4.d.cts} +27 -0
- package/dist/{hustle-S48t4lTZ.d.ts → hustle-C0Ltl5k4.d.ts} +27 -0
- package/dist/index.cjs +140 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +140 -6
- package/dist/index.js.map +1 -1
- package/dist/providers/index.d.cts +1 -1
- package/dist/providers/index.d.ts +1 -1
- package/package.json +2 -2
package/dist/hooks/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { HustleProvider, useHustle } from '../providers/index.cjs';
|
|
2
|
-
export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from '../hustle-
|
|
2
|
+
export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from '../hustle-C0Ltl5k4.cjs';
|
|
3
3
|
import { S as StoredPlugin, a as HydratedPlugin, H as HustlePlugin } from '../plugin-COr42J6-.cjs';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import 'hustle-incognito';
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { HustleProvider, useHustle } from '../providers/index.js';
|
|
2
|
-
export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from '../hustle-
|
|
2
|
+
export { A as Attachment, C as ChatMessage, b as ChatOptions, d as ChatResponse, H as HustleConfig, h as HustleContextValue, i as HustleProviderProps, M as Model, c as StreamChunk, g as StreamEndEvent, S as StreamOptions, T as ToolCall, f as ToolEndEvent, a as ToolResult, e as ToolStartEvent } from '../hustle-C0Ltl5k4.js';
|
|
3
3
|
import { S as StoredPlugin, a as HydratedPlugin, H as HustlePlugin } from '../plugin-COr42J6-.js';
|
|
4
4
|
import 'react/jsx-runtime';
|
|
5
5
|
import 'hustle-incognito';
|
|
@@ -5,12 +5,39 @@ import { HustleIncognitoClient } from 'hustle-incognito';
|
|
|
5
5
|
* These types mirror the HustleIncognitoClient types for use in React components
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Tool invocation with state tracking (AI SDK format)
|
|
10
|
+
*/
|
|
11
|
+
interface ToolInvocation {
|
|
12
|
+
state: 'call' | 'result';
|
|
13
|
+
step: number;
|
|
14
|
+
toolCallId: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
args?: Record<string, unknown>;
|
|
17
|
+
result?: unknown;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Message part for AI SDK compatibility
|
|
21
|
+
*/
|
|
22
|
+
type MessagePart = {
|
|
23
|
+
type: 'step-start';
|
|
24
|
+
} | {
|
|
25
|
+
type: 'text';
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'tool-invocation';
|
|
29
|
+
toolInvocation: ToolInvocation;
|
|
30
|
+
};
|
|
8
31
|
/**
|
|
9
32
|
* Chat message structure
|
|
10
33
|
*/
|
|
11
34
|
interface ChatMessage {
|
|
12
35
|
role: 'system' | 'user' | 'assistant';
|
|
13
36
|
content: string;
|
|
37
|
+
/** Tool invocations for this message (AI SDK format) */
|
|
38
|
+
toolInvocations?: ToolInvocation[];
|
|
39
|
+
/** Message parts for AI SDK compatibility */
|
|
40
|
+
parts?: MessagePart[];
|
|
14
41
|
}
|
|
15
42
|
/**
|
|
16
43
|
* Tool call information
|
|
@@ -5,12 +5,39 @@ import { HustleIncognitoClient } from 'hustle-incognito';
|
|
|
5
5
|
* These types mirror the HustleIncognitoClient types for use in React components
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Tool invocation with state tracking (AI SDK format)
|
|
10
|
+
*/
|
|
11
|
+
interface ToolInvocation {
|
|
12
|
+
state: 'call' | 'result';
|
|
13
|
+
step: number;
|
|
14
|
+
toolCallId: string;
|
|
15
|
+
toolName: string;
|
|
16
|
+
args?: Record<string, unknown>;
|
|
17
|
+
result?: unknown;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Message part for AI SDK compatibility
|
|
21
|
+
*/
|
|
22
|
+
type MessagePart = {
|
|
23
|
+
type: 'step-start';
|
|
24
|
+
} | {
|
|
25
|
+
type: 'text';
|
|
26
|
+
text: string;
|
|
27
|
+
} | {
|
|
28
|
+
type: 'tool-invocation';
|
|
29
|
+
toolInvocation: ToolInvocation;
|
|
30
|
+
};
|
|
8
31
|
/**
|
|
9
32
|
* Chat message structure
|
|
10
33
|
*/
|
|
11
34
|
interface ChatMessage {
|
|
12
35
|
role: 'system' | 'user' | 'assistant';
|
|
13
36
|
content: string;
|
|
37
|
+
/** Tool invocations for this message (AI SDK format) */
|
|
38
|
+
toolInvocations?: ToolInvocation[];
|
|
39
|
+
/** Message parts for AI SDK compatibility */
|
|
40
|
+
parts?: MessagePart[];
|
|
14
41
|
}
|
|
15
42
|
/**
|
|
16
43
|
* Tool call information
|
package/dist/index.cjs
CHANGED
|
@@ -4049,7 +4049,14 @@ function HustleChat({
|
|
|
4049
4049
|
setIsStreaming(true);
|
|
4050
4050
|
setCurrentToolCalls([]);
|
|
4051
4051
|
try {
|
|
4052
|
-
const chatMessages = messagesRef.current.filter((m) => !m.isStreaming).map((m) =>
|
|
4052
|
+
const chatMessages = messagesRef.current.filter((m) => !m.isStreaming).map((m) => {
|
|
4053
|
+
const msg = { role: m.role, content: m.content };
|
|
4054
|
+
if (m.role === "assistant" && m.toolInvocations && m.toolInvocations.length > 0) {
|
|
4055
|
+
msg.toolInvocations = m.toolInvocations;
|
|
4056
|
+
msg.parts = m.parts;
|
|
4057
|
+
}
|
|
4058
|
+
return msg;
|
|
4059
|
+
});
|
|
4053
4060
|
chatMessages.push({ role: "user", content: "continue" });
|
|
4054
4061
|
const stream = chatStream({
|
|
4055
4062
|
messages: chatMessages,
|
|
@@ -4057,6 +4064,9 @@ function HustleChat({
|
|
|
4057
4064
|
});
|
|
4058
4065
|
let fullContent = "";
|
|
4059
4066
|
const toolCallsAccumulated = [];
|
|
4067
|
+
const toolInvocationsAccumulated = [];
|
|
4068
|
+
const partsAccumulated = [{ type: "step-start" }];
|
|
4069
|
+
let stepCounter = 0;
|
|
4060
4070
|
for await (const chunk of stream) {
|
|
4061
4071
|
if (chunk.type === "text") {
|
|
4062
4072
|
fullContent += chunk.value;
|
|
@@ -4068,22 +4078,79 @@ function HustleChat({
|
|
|
4068
4078
|
} else if (chunk.type === "tool_call") {
|
|
4069
4079
|
const toolCall = chunk.value;
|
|
4070
4080
|
toolCallsAccumulated.push(toolCall);
|
|
4081
|
+
const invocation = {
|
|
4082
|
+
state: "call",
|
|
4083
|
+
step: stepCounter++,
|
|
4084
|
+
toolCallId: toolCall.toolCallId,
|
|
4085
|
+
toolName: toolCall.toolName,
|
|
4086
|
+
args: toolCall.args
|
|
4087
|
+
};
|
|
4088
|
+
toolInvocationsAccumulated.push(invocation);
|
|
4089
|
+
partsAccumulated.push({ type: "tool-invocation", toolInvocation: invocation });
|
|
4071
4090
|
setCurrentToolCalls([...toolCallsAccumulated]);
|
|
4072
4091
|
setMessages(
|
|
4073
4092
|
(prev) => prev.map(
|
|
4074
|
-
(m) => m.id === assistantMessage.id ? {
|
|
4093
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4094
|
+
...m,
|
|
4095
|
+
toolCalls: [...toolCallsAccumulated],
|
|
4096
|
+
toolInvocations: [...toolInvocationsAccumulated],
|
|
4097
|
+
parts: [...partsAccumulated]
|
|
4098
|
+
} : m
|
|
4075
4099
|
)
|
|
4076
4100
|
);
|
|
4077
4101
|
onToolCall?.(toolCall);
|
|
4102
|
+
} else if (chunk.type === "tool_result") {
|
|
4103
|
+
const toolResult = chunk.value;
|
|
4104
|
+
const invocationIndex = toolInvocationsAccumulated.findIndex(
|
|
4105
|
+
(inv) => inv.toolCallId === toolResult.toolCallId
|
|
4106
|
+
);
|
|
4107
|
+
if (invocationIndex !== -1) {
|
|
4108
|
+
toolInvocationsAccumulated[invocationIndex] = {
|
|
4109
|
+
...toolInvocationsAccumulated[invocationIndex],
|
|
4110
|
+
state: "result",
|
|
4111
|
+
result: toolResult.result
|
|
4112
|
+
};
|
|
4113
|
+
const partIndex = partsAccumulated.findIndex(
|
|
4114
|
+
(p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === toolResult.toolCallId
|
|
4115
|
+
);
|
|
4116
|
+
if (partIndex !== -1) {
|
|
4117
|
+
partsAccumulated[partIndex] = {
|
|
4118
|
+
type: "tool-invocation",
|
|
4119
|
+
toolInvocation: toolInvocationsAccumulated[invocationIndex]
|
|
4120
|
+
};
|
|
4121
|
+
}
|
|
4122
|
+
}
|
|
4123
|
+
setMessages(
|
|
4124
|
+
(prev) => prev.map(
|
|
4125
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4126
|
+
...m,
|
|
4127
|
+
toolInvocations: [...toolInvocationsAccumulated],
|
|
4128
|
+
parts: [...partsAccumulated]
|
|
4129
|
+
} : m
|
|
4130
|
+
)
|
|
4131
|
+
);
|
|
4078
4132
|
} else if (chunk.type === "error") {
|
|
4079
4133
|
console.error("Stream error:", chunk.value);
|
|
4080
4134
|
}
|
|
4081
4135
|
}
|
|
4082
4136
|
const processedResponse = await stream.response;
|
|
4083
4137
|
const finalContent = processedResponse?.content || fullContent || "(No response)";
|
|
4138
|
+
const finalParts = [{ type: "step-start" }];
|
|
4139
|
+
if (finalContent) {
|
|
4140
|
+
finalParts.push({ type: "text", text: finalContent });
|
|
4141
|
+
}
|
|
4142
|
+
for (const inv of toolInvocationsAccumulated) {
|
|
4143
|
+
finalParts.push({ type: "tool-invocation", toolInvocation: inv });
|
|
4144
|
+
}
|
|
4084
4145
|
setMessages(
|
|
4085
4146
|
(prev) => prev.map(
|
|
4086
|
-
(m) => m.id === assistantMessage.id ? {
|
|
4147
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4148
|
+
...m,
|
|
4149
|
+
isStreaming: false,
|
|
4150
|
+
content: finalContent,
|
|
4151
|
+
toolInvocations: toolInvocationsAccumulated.length > 0 ? toolInvocationsAccumulated : void 0,
|
|
4152
|
+
parts: toolInvocationsAccumulated.length > 0 ? finalParts : void 0
|
|
4153
|
+
} : m
|
|
4087
4154
|
)
|
|
4088
4155
|
);
|
|
4089
4156
|
onResponse?.(finalContent);
|
|
@@ -4145,7 +4212,14 @@ function HustleChat({
|
|
|
4145
4212
|
setIsStreaming(true);
|
|
4146
4213
|
setCurrentToolCalls([]);
|
|
4147
4214
|
try {
|
|
4148
|
-
const chatMessages = messages.filter((m) => !m.isStreaming).map((m) =>
|
|
4215
|
+
const chatMessages = messages.filter((m) => !m.isStreaming).map((m) => {
|
|
4216
|
+
const msg = { role: m.role, content: m.content };
|
|
4217
|
+
if (m.role === "assistant" && m.toolInvocations && m.toolInvocations.length > 0) {
|
|
4218
|
+
msg.toolInvocations = m.toolInvocations;
|
|
4219
|
+
msg.parts = m.parts;
|
|
4220
|
+
}
|
|
4221
|
+
return msg;
|
|
4222
|
+
});
|
|
4149
4223
|
chatMessages.push({ role: "user", content });
|
|
4150
4224
|
const stream = chatStream({
|
|
4151
4225
|
messages: chatMessages,
|
|
@@ -4155,6 +4229,9 @@ function HustleChat({
|
|
|
4155
4229
|
setAttachments([]);
|
|
4156
4230
|
let fullContent = "";
|
|
4157
4231
|
const toolCallsAccumulated = [];
|
|
4232
|
+
const toolInvocationsAccumulated = [];
|
|
4233
|
+
const partsAccumulated = [{ type: "step-start" }];
|
|
4234
|
+
let stepCounter = 0;
|
|
4158
4235
|
for await (const chunk of stream) {
|
|
4159
4236
|
if (chunk.type === "text") {
|
|
4160
4237
|
fullContent += chunk.value;
|
|
@@ -4166,22 +4243,79 @@ function HustleChat({
|
|
|
4166
4243
|
} else if (chunk.type === "tool_call") {
|
|
4167
4244
|
const toolCall = chunk.value;
|
|
4168
4245
|
toolCallsAccumulated.push(toolCall);
|
|
4246
|
+
const invocation = {
|
|
4247
|
+
state: "call",
|
|
4248
|
+
step: stepCounter++,
|
|
4249
|
+
toolCallId: toolCall.toolCallId,
|
|
4250
|
+
toolName: toolCall.toolName,
|
|
4251
|
+
args: toolCall.args
|
|
4252
|
+
};
|
|
4253
|
+
toolInvocationsAccumulated.push(invocation);
|
|
4254
|
+
partsAccumulated.push({ type: "tool-invocation", toolInvocation: invocation });
|
|
4169
4255
|
setCurrentToolCalls([...toolCallsAccumulated]);
|
|
4170
4256
|
setMessages(
|
|
4171
4257
|
(prev) => prev.map(
|
|
4172
|
-
(m) => m.id === assistantMessage.id ? {
|
|
4258
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4259
|
+
...m,
|
|
4260
|
+
toolCalls: [...toolCallsAccumulated],
|
|
4261
|
+
toolInvocations: [...toolInvocationsAccumulated],
|
|
4262
|
+
parts: [...partsAccumulated]
|
|
4263
|
+
} : m
|
|
4173
4264
|
)
|
|
4174
4265
|
);
|
|
4175
4266
|
onToolCall?.(toolCall);
|
|
4267
|
+
} else if (chunk.type === "tool_result") {
|
|
4268
|
+
const toolResult = chunk.value;
|
|
4269
|
+
const invocationIndex = toolInvocationsAccumulated.findIndex(
|
|
4270
|
+
(inv) => inv.toolCallId === toolResult.toolCallId
|
|
4271
|
+
);
|
|
4272
|
+
if (invocationIndex !== -1) {
|
|
4273
|
+
toolInvocationsAccumulated[invocationIndex] = {
|
|
4274
|
+
...toolInvocationsAccumulated[invocationIndex],
|
|
4275
|
+
state: "result",
|
|
4276
|
+
result: toolResult.result
|
|
4277
|
+
};
|
|
4278
|
+
const partIndex = partsAccumulated.findIndex(
|
|
4279
|
+
(p) => p.type === "tool-invocation" && p.toolInvocation.toolCallId === toolResult.toolCallId
|
|
4280
|
+
);
|
|
4281
|
+
if (partIndex !== -1) {
|
|
4282
|
+
partsAccumulated[partIndex] = {
|
|
4283
|
+
type: "tool-invocation",
|
|
4284
|
+
toolInvocation: toolInvocationsAccumulated[invocationIndex]
|
|
4285
|
+
};
|
|
4286
|
+
}
|
|
4287
|
+
}
|
|
4288
|
+
setMessages(
|
|
4289
|
+
(prev) => prev.map(
|
|
4290
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4291
|
+
...m,
|
|
4292
|
+
toolInvocations: [...toolInvocationsAccumulated],
|
|
4293
|
+
parts: [...partsAccumulated]
|
|
4294
|
+
} : m
|
|
4295
|
+
)
|
|
4296
|
+
);
|
|
4176
4297
|
} else if (chunk.type === "error") {
|
|
4177
4298
|
console.error("Stream error:", chunk.value);
|
|
4178
4299
|
}
|
|
4179
4300
|
}
|
|
4180
4301
|
const processedResponse = await stream.response;
|
|
4181
4302
|
const finalContent = processedResponse?.content || fullContent || "(No response)";
|
|
4303
|
+
const finalParts = [{ type: "step-start" }];
|
|
4304
|
+
if (finalContent) {
|
|
4305
|
+
finalParts.push({ type: "text", text: finalContent });
|
|
4306
|
+
}
|
|
4307
|
+
for (const inv of toolInvocationsAccumulated) {
|
|
4308
|
+
finalParts.push({ type: "tool-invocation", toolInvocation: inv });
|
|
4309
|
+
}
|
|
4182
4310
|
setMessages(
|
|
4183
4311
|
(prev) => prev.map(
|
|
4184
|
-
(m) => m.id === assistantMessage.id ? {
|
|
4312
|
+
(m) => m.id === assistantMessage.id ? {
|
|
4313
|
+
...m,
|
|
4314
|
+
isStreaming: false,
|
|
4315
|
+
content: finalContent,
|
|
4316
|
+
toolInvocations: toolInvocationsAccumulated.length > 0 ? toolInvocationsAccumulated : void 0,
|
|
4317
|
+
parts: toolInvocationsAccumulated.length > 0 ? finalParts : void 0
|
|
4318
|
+
} : m
|
|
4185
4319
|
)
|
|
4186
4320
|
);
|
|
4187
4321
|
onResponse?.(finalContent);
|