@nextclaw/ui 0.15.17 → 0.15.18
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/CHANGELOG.md +10 -0
- package/dist/assets/{app-presenter-provider-C9AcZKKs.js → app-presenter-provider-De7Zwitu.js} +14 -14
- package/dist/assets/{appearance-settings-page-CiD9Ey8f.js → appearance-settings-page-BkQaPtQ-.js} +1 -1
- package/dist/assets/{chat-page-B0cC3jsB.js → chat-page-AvOuaxuv.js} +1 -1
- package/dist/assets/{index-bOqpao-w.js → index-B5AoUrMf.js} +2 -2
- package/dist/assets/remote-B6TXClIg.js +1 -0
- package/dist/assets/{runtime-config-page-CbSrKeJt.js → runtime-config-page-BLrTVO3n.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +6 -6
- package/src/features/chat/components/conversation/__tests__/chat-conversation-content.test.tsx +11 -0
- package/src/features/chat/components/conversation/chat-conversation-content.tsx +7 -1
- package/src/features/chat/features/conversation/components/__tests__/session-conversation-area.test.tsx +50 -4
- package/src/features/chat/features/conversation/components/session-conversation-area.tsx +25 -1
- package/src/features/chat/features/conversation/components/session-conversation-input.tsx +3 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-input-state.test.tsx +41 -0
- package/src/features/chat/features/conversation/hooks/__tests__/use-session-conversation-slash-commands.test.tsx +28 -0
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-query.ts +1 -1
- package/src/features/chat/features/conversation/hooks/use-session-conversation-input-state.ts +0 -1
- package/src/features/chat/features/conversation/hooks/use-session-conversation-preference-actions.ts +10 -11
- package/src/features/chat/features/conversation/hooks/use-session-conversation-slash-commands.ts +5 -2
- package/src/features/chat/features/message/components/chat-message-list.container.tsx +12 -9
- package/src/features/chat/features/ncp/hooks/__tests__/use-hydrated-ncp-agent.test.tsx +122 -1
- package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime-queue.test.tsx +9 -2
- package/src/features/chat/features/ncp/hooks/__tests__/use-ncp-agent-runtime.test.tsx +107 -1
- package/dist/assets/remote-B0nlynVp.js +0 -1
|
@@ -200,12 +200,118 @@ describe("useNcpAgentRuntime", () => {
|
|
|
200
200
|
assistantMessageId: "assistant-1",
|
|
201
201
|
runId: "run-1",
|
|
202
202
|
});
|
|
203
|
-
expect(result.current.visibleMessages).toEqual([
|
|
203
|
+
expect(result.current.visibleMessages).toEqual([
|
|
204
|
+
expect.objectContaining({
|
|
205
|
+
...envelope.message,
|
|
206
|
+
sessionId: "session-created",
|
|
207
|
+
}),
|
|
208
|
+
]);
|
|
204
209
|
expect(client.stop).not.toHaveBeenCalled();
|
|
205
210
|
|
|
206
211
|
rerender({ sessionId: "session-created" });
|
|
207
212
|
});
|
|
208
213
|
|
|
214
|
+
it("shows an existing-session user message before send returns and deduplicates the server event", async () => {
|
|
215
|
+
const client = new DeferredSendClient();
|
|
216
|
+
const manager = new DefaultNcpAgentConversationStateManager();
|
|
217
|
+
const envelope: NcpAgentSendEnvelope = {
|
|
218
|
+
sessionId: "session-existing",
|
|
219
|
+
message: {
|
|
220
|
+
id: "user-optimistic",
|
|
221
|
+
sessionId: "session-existing",
|
|
222
|
+
role: "user",
|
|
223
|
+
status: "final",
|
|
224
|
+
parts: [{ type: "text", text: "hello now" }],
|
|
225
|
+
timestamp: now,
|
|
226
|
+
},
|
|
227
|
+
};
|
|
228
|
+
let releaseSend = () => {};
|
|
229
|
+
client.send.mockImplementationOnce(
|
|
230
|
+
(pendingEnvelope) =>
|
|
231
|
+
new Promise((resolve) => {
|
|
232
|
+
releaseSend = () =>
|
|
233
|
+
resolve({
|
|
234
|
+
sessionId: "session-existing",
|
|
235
|
+
userMessageId: pendingEnvelope.message.id,
|
|
236
|
+
assistantMessageId: "assistant-1",
|
|
237
|
+
runId: "run-1",
|
|
238
|
+
});
|
|
239
|
+
}),
|
|
240
|
+
);
|
|
241
|
+
const { result } = renderHook(() =>
|
|
242
|
+
useNcpAgentRuntime({
|
|
243
|
+
sessionId: "session-existing",
|
|
244
|
+
client,
|
|
245
|
+
manager: manager as never,
|
|
246
|
+
}),
|
|
247
|
+
);
|
|
248
|
+
|
|
249
|
+
let sendPromise!: ReturnType<typeof result.current.send>;
|
|
250
|
+
act(() => {
|
|
251
|
+
sendPromise = result.current.send(envelope);
|
|
252
|
+
});
|
|
253
|
+
|
|
254
|
+
await waitFor(() => {
|
|
255
|
+
expect(result.current.visibleMessages).toEqual([envelope.message]);
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
await act(async () => {
|
|
259
|
+
await client.emit({
|
|
260
|
+
type: NcpEventType.MessageSent,
|
|
261
|
+
payload: {
|
|
262
|
+
sessionId: "session-existing",
|
|
263
|
+
message: envelope.message as NcpMessage,
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
});
|
|
267
|
+
await waitFor(() => {
|
|
268
|
+
expect(result.current.visibleMessages).toHaveLength(1);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
await act(async () => {
|
|
272
|
+
releaseSend();
|
|
273
|
+
await sendPromise;
|
|
274
|
+
});
|
|
275
|
+
expect(result.current.visibleMessages).toEqual([envelope.message]);
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it("marks an optimistic user message as failed when send fails", async () => {
|
|
279
|
+
const client = new DeferredSendClient();
|
|
280
|
+
const manager = new DefaultNcpAgentConversationStateManager();
|
|
281
|
+
const envelope: NcpAgentSendEnvelope = {
|
|
282
|
+
sessionId: "session-existing",
|
|
283
|
+
message: {
|
|
284
|
+
id: "user-failed",
|
|
285
|
+
sessionId: "session-existing",
|
|
286
|
+
role: "user",
|
|
287
|
+
status: "final",
|
|
288
|
+
parts: [{ type: "text", text: "please retry" }],
|
|
289
|
+
timestamp: now,
|
|
290
|
+
},
|
|
291
|
+
};
|
|
292
|
+
client.send.mockRejectedValueOnce(new Error("network unavailable"));
|
|
293
|
+
const { result } = renderHook(() =>
|
|
294
|
+
useNcpAgentRuntime({
|
|
295
|
+
sessionId: "session-existing",
|
|
296
|
+
client,
|
|
297
|
+
manager: manager as never,
|
|
298
|
+
}),
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
await act(async () => {
|
|
302
|
+
await expect(result.current.send(envelope)).rejects.toThrow(
|
|
303
|
+
"network unavailable",
|
|
304
|
+
);
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
expect(result.current.visibleMessages).toEqual([
|
|
308
|
+
expect.objectContaining({
|
|
309
|
+
...envelope.message,
|
|
310
|
+
status: "error",
|
|
311
|
+
}),
|
|
312
|
+
]);
|
|
313
|
+
});
|
|
314
|
+
|
|
209
315
|
it("aborts by session id even before a hydrated active run reaches local state", async () => {
|
|
210
316
|
const client = new DeferredSendClient();
|
|
211
317
|
const manager = new DefaultNcpAgentConversationStateManager();
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Z as e}from"./app-presenter-provider-C9AcZKKs.js";export{e as RemoteAccessPage};
|