@steerable/agent-ui 0.6.62 → 0.6.63
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.
|
@@ -32,6 +32,7 @@ export function useChatList(options) {
|
|
|
32
32
|
const pageRef = useRef(1);
|
|
33
33
|
const hasMoreRef = useRef(false);
|
|
34
34
|
const loadingMoreRef = useRef(false);
|
|
35
|
+
const failedPageRef = useRef(null);
|
|
35
36
|
const mountedRef = useRef(true);
|
|
36
37
|
useEffect(() => {
|
|
37
38
|
mountedRef.current = true;
|
|
@@ -49,6 +50,7 @@ export function useChatList(options) {
|
|
|
49
50
|
setHasMore(res.hasMore);
|
|
50
51
|
hasMoreRef.current = res.hasMore;
|
|
51
52
|
pageRef.current = 1;
|
|
53
|
+
failedPageRef.current = null;
|
|
52
54
|
setError(null);
|
|
53
55
|
}
|
|
54
56
|
catch (err) {
|
|
@@ -72,12 +74,15 @@ export function useChatList(options) {
|
|
|
72
74
|
}
|
|
73
75
|
}, []);
|
|
74
76
|
const loadMoreChats = useCallback(async () => {
|
|
75
|
-
|
|
77
|
+
const next = pageRef.current + 1;
|
|
78
|
+
if (!hasMoreRef.current ||
|
|
79
|
+
loadingMoreRef.current ||
|
|
80
|
+
failedPageRef.current === next) {
|
|
76
81
|
return;
|
|
82
|
+
}
|
|
77
83
|
loadingMoreRef.current = true;
|
|
78
84
|
setLoadingMore(true);
|
|
79
85
|
try {
|
|
80
|
-
const next = pageRef.current + 1;
|
|
81
86
|
const res = await transportRef.current.listChats({ page: next, pageSize });
|
|
82
87
|
if (!mountedRef.current)
|
|
83
88
|
return;
|
|
@@ -94,8 +99,10 @@ export function useChatList(options) {
|
|
|
94
99
|
setHasMore(res.hasMore);
|
|
95
100
|
hasMoreRef.current = res.hasMore;
|
|
96
101
|
pageRef.current = next;
|
|
102
|
+
failedPageRef.current = null;
|
|
97
103
|
}
|
|
98
104
|
catch (err) {
|
|
105
|
+
failedPageRef.current = next;
|
|
99
106
|
if (mountedRef.current)
|
|
100
107
|
setError(err instanceof Error ? err : new Error(String(err)));
|
|
101
108
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@steerable/agent-ui",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.63",
|
|
4
4
|
"description": "Steerable framework Tier 4 — headless React hooks (useAgentSession, useChatStream, useToolCallStatus) and Tailwind-themed components (ChatPanel, MessageList, OrchestrationPlanCard, ToolCallRenderer, SSEStreamView) for embedding Steerable agents in any React app.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"homepage": "https://steerableframework.com/storybook/",
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
"README.md"
|
|
58
58
|
],
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@steerable/agent-protocol": "0.6.
|
|
60
|
+
"@steerable/agent-protocol": "0.6.63"
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"react": ">=18.0.0",
|
|
@@ -99,6 +99,36 @@ describe('useChatList', () => {
|
|
|
99
99
|
expect(result.current.chats.map((c) => c.id)).toEqual(['c1', 'c2', 'c3']);
|
|
100
100
|
});
|
|
101
101
|
|
|
102
|
+
it('does not automatically retry a failed page until the list is refreshed', async () => {
|
|
103
|
+
const { transport, listChats } = makeTransport();
|
|
104
|
+
listChats.mockImplementation(async ({ page }: { page: number }) => {
|
|
105
|
+
if (page === 2) throw new Error('second page unavailable');
|
|
106
|
+
return {
|
|
107
|
+
chats: [
|
|
108
|
+
{ id: 'c1', title: 'First' },
|
|
109
|
+
{ id: 'c2', title: 'Second' },
|
|
110
|
+
],
|
|
111
|
+
hasMore: true,
|
|
112
|
+
};
|
|
113
|
+
});
|
|
114
|
+
const { result } = renderHook(() => useChatList({ transport, pageSize: 50 }));
|
|
115
|
+
await waitFor(() => expect(result.current.chats.length).toBe(2));
|
|
116
|
+
|
|
117
|
+
await act(async () => {
|
|
118
|
+
await result.current.loadMoreChats();
|
|
119
|
+
await result.current.loadMoreChats();
|
|
120
|
+
});
|
|
121
|
+
expect(listChats).toHaveBeenCalledTimes(2);
|
|
122
|
+
expect(result.current.error?.message).toBe('second page unavailable');
|
|
123
|
+
expect(result.current.chats.map((chat) => chat.id)).toEqual(['c1', 'c2']);
|
|
124
|
+
|
|
125
|
+
await act(async () => {
|
|
126
|
+
await result.current.refreshChats();
|
|
127
|
+
await result.current.loadMoreChats();
|
|
128
|
+
});
|
|
129
|
+
expect(listChats).toHaveBeenCalledTimes(4);
|
|
130
|
+
});
|
|
131
|
+
|
|
102
132
|
it('patchChatTitle updates without re-fetching', async () => {
|
|
103
133
|
const { transport, listChats } = makeTransport();
|
|
104
134
|
const { result } = renderHook(() => useChatList({ transport, pageSize: 50 }));
|
package/src/state/useChatList.ts
CHANGED
|
@@ -90,6 +90,7 @@ export function useChatList<TChat, TAgent>(
|
|
|
90
90
|
const pageRef = useRef(1);
|
|
91
91
|
const hasMoreRef = useRef(false);
|
|
92
92
|
const loadingMoreRef = useRef(false);
|
|
93
|
+
const failedPageRef = useRef<number | null>(null);
|
|
93
94
|
const mountedRef = useRef(true);
|
|
94
95
|
|
|
95
96
|
useEffect(() => {
|
|
@@ -108,6 +109,7 @@ export function useChatList<TChat, TAgent>(
|
|
|
108
109
|
setHasMore(res.hasMore);
|
|
109
110
|
hasMoreRef.current = res.hasMore;
|
|
110
111
|
pageRef.current = 1;
|
|
112
|
+
failedPageRef.current = null;
|
|
111
113
|
setError(null);
|
|
112
114
|
} catch (err) {
|
|
113
115
|
if (mountedRef.current) setError(err instanceof Error ? err : new Error(String(err)));
|
|
@@ -126,11 +128,17 @@ export function useChatList<TChat, TAgent>(
|
|
|
126
128
|
}, []);
|
|
127
129
|
|
|
128
130
|
const loadMoreChats = useCallback(async () => {
|
|
129
|
-
|
|
131
|
+
const next = pageRef.current + 1;
|
|
132
|
+
if (
|
|
133
|
+
!hasMoreRef.current ||
|
|
134
|
+
loadingMoreRef.current ||
|
|
135
|
+
failedPageRef.current === next
|
|
136
|
+
) {
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
130
139
|
loadingMoreRef.current = true;
|
|
131
140
|
setLoadingMore(true);
|
|
132
141
|
try {
|
|
133
|
-
const next = pageRef.current + 1;
|
|
134
142
|
const res = await transportRef.current.listChats({ page: next, pageSize });
|
|
135
143
|
if (!mountedRef.current) return;
|
|
136
144
|
setChats((prev) => {
|
|
@@ -147,7 +155,9 @@ export function useChatList<TChat, TAgent>(
|
|
|
147
155
|
setHasMore(res.hasMore);
|
|
148
156
|
hasMoreRef.current = res.hasMore;
|
|
149
157
|
pageRef.current = next;
|
|
158
|
+
failedPageRef.current = null;
|
|
150
159
|
} catch (err) {
|
|
160
|
+
failedPageRef.current = next;
|
|
151
161
|
if (mountedRef.current) setError(err instanceof Error ? err : new Error(String(err)));
|
|
152
162
|
} finally {
|
|
153
163
|
loadingMoreRef.current = false;
|