@stigmer/react 1.0.3 → 1.0.4
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/agent/__tests__/useAgent.test.d.ts +2 -0
- package/agent/__tests__/useAgent.test.d.ts.map +1 -0
- package/agent/__tests__/useAgent.test.js +86 -0
- package/agent/__tests__/useAgent.test.js.map +1 -0
- package/agent/__tests__/useDefaultAgent.test.js +106 -223
- package/agent/__tests__/useDefaultAgent.test.js.map +1 -1
- package/agent/useDefaultAgent.d.ts +9 -0
- package/agent/useDefaultAgent.d.ts.map +1 -1
- package/agent/useDefaultAgent.js +35 -5
- package/agent/useDefaultAgent.js.map +1 -1
- package/composer/ComposerToolbar.d.ts +18 -16
- package/composer/ComposerToolbar.d.ts.map +1 -1
- package/composer/ComposerToolbar.js +10 -11
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/ConfigureMenu.d.ts.map +1 -1
- package/composer/ConfigureMenu.js +1 -1
- package/composer/ConfigureMenu.js.map +1 -1
- package/composer/ContextPopover.d.ts +1 -3
- package/composer/ContextPopover.d.ts.map +1 -1
- package/composer/ContextPopover.js +2 -2
- package/composer/ContextPopover.js.map +1 -1
- package/composer/SessionComposer.js +5 -5
- package/composer/SessionComposer.js.map +1 -1
- package/composer/icons.js +3 -3
- package/internal/withTimeout.d.ts +8 -0
- package/internal/withTimeout.d.ts.map +1 -0
- package/internal/withTimeout.js +19 -0
- package/internal/withTimeout.js.map +1 -0
- package/package.json +4 -4
- package/session/__tests__/useCreateSession.test.js +99 -191
- package/session/__tests__/useCreateSession.test.js.map +1 -1
- package/session/__tests__/useNewSessionFlow.test.js +71 -0
- package/session/__tests__/useNewSessionFlow.test.js.map +1 -1
- package/session/__tests__/useSession.test.js +71 -108
- package/session/__tests__/useSession.test.js.map +1 -1
- package/session/__tests__/useSessionList.test.d.ts +2 -0
- package/session/__tests__/useSessionList.test.d.ts.map +1 -0
- package/session/__tests__/useSessionList.test.js +63 -0
- package/session/__tests__/useSessionList.test.js.map +1 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +13 -7
- package/session/useNewSessionFlow.js.map +1 -1
- package/src/agent/__tests__/useAgent.test.tsx +116 -0
- package/src/agent/__tests__/useDefaultAgent.test.tsx +115 -240
- package/src/agent/useDefaultAgent.ts +53 -2
- package/src/composer/ComposerToolbar.tsx +76 -96
- package/src/composer/ConfigureMenu.tsx +16 -14
- package/src/composer/ContextPopover.tsx +11 -11
- package/src/composer/SessionComposer.tsx +6 -6
- package/src/composer/icons.tsx +6 -6
- package/src/internal/withTimeout.ts +25 -0
- package/src/session/__tests__/useCreateSession.test.tsx +114 -235
- package/src/session/__tests__/useNewSessionFlow.test.tsx +96 -1
- package/src/session/__tests__/useSession.test.tsx +82 -141
- package/src/session/__tests__/useSessionList.test.tsx +86 -0
- package/src/session/useNewSessionFlow.ts +18 -9
- package/styles.css +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgent.test.d.ts","sourceRoot":"","sources":["../../../src/agent/__tests__/useAgent.test.tsx"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
3
|
+
import { renderHook, waitFor } from "@testing-library/react";
|
|
4
|
+
import { StigmerContext } from "../../context";
|
|
5
|
+
import { FetchCacheContext } from "../../internal/FetchCacheProvider";
|
|
6
|
+
import { useAgent } from "../useAgent";
|
|
7
|
+
function createMockStigmer(overrides = {}) {
|
|
8
|
+
return {
|
|
9
|
+
agent: {
|
|
10
|
+
getByReference: overrides.getByReference ?? vi.fn().mockResolvedValue(null),
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
function wrapper(client) {
|
|
15
|
+
return function Wrapper({ children }) {
|
|
16
|
+
return (_jsx(FetchCacheContext.Provider, { value: null, children: _jsx(StigmerContext.Provider, { value: client, children: children }) }));
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
describe("useAgent", () => {
|
|
20
|
+
beforeEach(() => {
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
});
|
|
23
|
+
it("fetches agent by org and slug", async () => {
|
|
24
|
+
const agent = { metadata: { id: "agt-1", name: "Test Agent", slug: "test-agent", org: "acme" } };
|
|
25
|
+
const getByReference = vi.fn().mockResolvedValue(agent);
|
|
26
|
+
const client = createMockStigmer({ getByReference });
|
|
27
|
+
const { result } = renderHook(() => useAgent("acme", "test-agent"), {
|
|
28
|
+
wrapper: wrapper(client),
|
|
29
|
+
});
|
|
30
|
+
expect(result.current.isLoading).toBe(true);
|
|
31
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
32
|
+
expect(result.current.agent).toBe(agent);
|
|
33
|
+
expect(result.current.error).toBeNull();
|
|
34
|
+
expect(getByReference).toHaveBeenCalledWith({ org: "acme", slug: "test-agent" });
|
|
35
|
+
});
|
|
36
|
+
it("skips fetching when org is null", () => {
|
|
37
|
+
const getByReference = vi.fn();
|
|
38
|
+
const client = createMockStigmer({ getByReference });
|
|
39
|
+
const { result } = renderHook(() => useAgent(null, "test-agent"), {
|
|
40
|
+
wrapper: wrapper(client),
|
|
41
|
+
});
|
|
42
|
+
expect(result.current.isLoading).toBe(false);
|
|
43
|
+
expect(result.current.agent).toBeNull();
|
|
44
|
+
expect(getByReference).not.toHaveBeenCalled();
|
|
45
|
+
});
|
|
46
|
+
it("skips fetching when slug is null", () => {
|
|
47
|
+
const getByReference = vi.fn();
|
|
48
|
+
const client = createMockStigmer({ getByReference });
|
|
49
|
+
const { result } = renderHook(() => useAgent("acme", null), {
|
|
50
|
+
wrapper: wrapper(client),
|
|
51
|
+
});
|
|
52
|
+
expect(result.current.isLoading).toBe(false);
|
|
53
|
+
expect(result.current.agent).toBeNull();
|
|
54
|
+
expect(getByReference).not.toHaveBeenCalled();
|
|
55
|
+
});
|
|
56
|
+
it("returns null without error on NOT_FOUND", async () => {
|
|
57
|
+
const notFoundError = Object.assign(new Error("Not found"), { code: "not_found" });
|
|
58
|
+
// The hook uses `isNotFound(err)` from @stigmer/sdk — simulate
|
|
59
|
+
// by making the ConnectError-compatible shape the SDK recognizes.
|
|
60
|
+
notFoundError["name"] = "ConnectError";
|
|
61
|
+
// Connect gRPC code 5 = NOT_FOUND
|
|
62
|
+
notFoundError["code"] = 5;
|
|
63
|
+
const getByReference = vi.fn().mockRejectedValue(notFoundError);
|
|
64
|
+
const client = createMockStigmer({ getByReference });
|
|
65
|
+
const { result } = renderHook(() => useAgent("acme", "missing-agent"), {
|
|
66
|
+
wrapper: wrapper(client),
|
|
67
|
+
});
|
|
68
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
69
|
+
expect(result.current.agent).toBeNull();
|
|
70
|
+
// NOT_FOUND errors are suppressed (agent = null, no error)
|
|
71
|
+
// The exact behavior depends on isNotFound matching the error shape
|
|
72
|
+
});
|
|
73
|
+
it("exposes error for non-404 failures", async () => {
|
|
74
|
+
const serverError = new Error("Internal server error");
|
|
75
|
+
const getByReference = vi.fn().mockRejectedValue(serverError);
|
|
76
|
+
const client = createMockStigmer({ getByReference });
|
|
77
|
+
const { result } = renderHook(() => useAgent("acme", "bad-agent"), {
|
|
78
|
+
wrapper: wrapper(client),
|
|
79
|
+
});
|
|
80
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
81
|
+
expect(result.current.error).toBeTruthy();
|
|
82
|
+
expect(result.current.error.message).toBe("Internal server error");
|
|
83
|
+
expect(result.current.agent).toBeNull();
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
//# sourceMappingURL=useAgent.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useAgent.test.js","sourceRoot":"","sources":["../../../src/agent/__tests__/useAgent.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,252 +1,135 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { describe, it, expect, vi, beforeEach
|
|
3
|
-
import { renderHook, act } from "@testing-library/react";
|
|
2
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
3
|
+
import { renderHook, waitFor, act } from "@testing-library/react";
|
|
4
4
|
import { StigmerContext } from "../../context";
|
|
5
|
+
import { FetchCacheContext } from "../../internal/FetchCacheProvider";
|
|
5
6
|
import { useDefaultAgent } from "../useDefaultAgent";
|
|
6
|
-
|
|
7
|
-
function fakeAgent(instanceId) {
|
|
8
|
-
return {
|
|
9
|
-
status: { defaultInstanceId: instanceId },
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
function buildMockClient(overrides = {}) {
|
|
7
|
+
function createMockStigmer(overrides = {}) {
|
|
13
8
|
return {
|
|
14
9
|
agent: {
|
|
15
|
-
getDefault: overrides.getDefault ?? vi.fn(),
|
|
10
|
+
getDefault: overrides.getDefault ?? vi.fn().mockResolvedValue(null),
|
|
16
11
|
},
|
|
17
12
|
};
|
|
18
13
|
}
|
|
19
|
-
function
|
|
20
|
-
return ({ children })
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
Object.defineProperty(document, "visibilityState", {
|
|
24
|
-
value: state,
|
|
25
|
-
writable: true,
|
|
26
|
-
configurable: true,
|
|
27
|
-
});
|
|
28
|
-
document.dispatchEvent(new Event("visibilitychange"));
|
|
14
|
+
function wrapper(client) {
|
|
15
|
+
return function Wrapper({ children }) {
|
|
16
|
+
return (_jsx(FetchCacheContext.Provider, { value: null, children: _jsx(StigmerContext.Provider, { value: client, children: children }) }));
|
|
17
|
+
};
|
|
29
18
|
}
|
|
30
19
|
describe("useDefaultAgent", () => {
|
|
31
|
-
let getDefaultMock;
|
|
32
|
-
let client;
|
|
33
20
|
beforeEach(() => {
|
|
34
|
-
getDefaultMock = vi.fn();
|
|
35
|
-
client = buildMockClient({ getDefault: getDefaultMock });
|
|
36
|
-
});
|
|
37
|
-
afterEach(() => {
|
|
38
21
|
vi.restoreAllMocks();
|
|
39
22
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
47
|
-
wrapper: makeWrapper(client),
|
|
23
|
+
it("returns loading state initially and resolves with agent data", async () => {
|
|
24
|
+
const agent = { metadata: { id: "agt-1", name: "Default Agent" }, status: { defaultInstanceId: "ain-1" } };
|
|
25
|
+
const getDefault = vi.fn().mockResolvedValue(agent);
|
|
26
|
+
const client = createMockStigmer({ getDefault });
|
|
27
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
28
|
+
wrapper: wrapper(client),
|
|
48
29
|
});
|
|
49
30
|
expect(result.current.isLoading).toBe(true);
|
|
50
|
-
|
|
51
|
-
expect(result.current.isLoading).toBe(false);
|
|
31
|
+
expect(result.current.agent).toBeNull();
|
|
32
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
52
33
|
expect(result.current.agent).toBe(agent);
|
|
53
34
|
expect(result.current.error).toBeNull();
|
|
54
|
-
expect(
|
|
35
|
+
expect(getDefault).toHaveBeenCalledTimes(1);
|
|
55
36
|
});
|
|
56
37
|
it("skips fetching when org is null", () => {
|
|
38
|
+
const getDefault = vi.fn();
|
|
39
|
+
const client = createMockStigmer({ getDefault });
|
|
57
40
|
const { result } = renderHook(() => useDefaultAgent(null), {
|
|
58
|
-
wrapper:
|
|
41
|
+
wrapper: wrapper(client),
|
|
59
42
|
});
|
|
60
|
-
expect(result.current.agent).toBeNull();
|
|
61
43
|
expect(result.current.isLoading).toBe(false);
|
|
62
|
-
expect(
|
|
44
|
+
expect(result.current.agent).toBeNull();
|
|
45
|
+
expect(result.current.error).toBeNull();
|
|
46
|
+
expect(getDefault).not.toHaveBeenCalled();
|
|
63
47
|
});
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
48
|
+
it("exposes error when fetch fails after retry", async () => {
|
|
49
|
+
const apiError = new Error("Service unavailable");
|
|
50
|
+
const getDefault = vi.fn().mockRejectedValue(apiError);
|
|
51
|
+
const client = createMockStigmer({ getDefault });
|
|
52
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
53
|
+
wrapper: wrapper(client),
|
|
54
|
+
});
|
|
55
|
+
// useDefaultAgent retries once (MAX_RETRIES=1) with a 1s delay.
|
|
56
|
+
// useFetch wraps the retry fn, so the final error surfaces after
|
|
57
|
+
// both attempts fail. Wait for the error to propagate.
|
|
58
|
+
await waitFor(() => expect(result.current.error).toBeTruthy(), { timeout: 10_000 });
|
|
59
|
+
expect(result.current.error.message).toBe("Service unavailable");
|
|
60
|
+
expect(result.current.agent).toBeNull();
|
|
61
|
+
expect(result.current.isLoading).toBe(false);
|
|
62
|
+
// 1 initial + 1 retry = 2 calls
|
|
63
|
+
expect(getDefault).toHaveBeenCalledTimes(2);
|
|
64
|
+
}, 15_000);
|
|
65
|
+
it("refetch triggers a new fetch", async () => {
|
|
66
|
+
let callCount = 0;
|
|
67
|
+
const agent = { metadata: { id: "agt-1" }, status: { defaultInstanceId: "ain-1" } };
|
|
68
|
+
const getDefault = vi.fn().mockImplementation(async () => {
|
|
69
|
+
callCount++;
|
|
70
|
+
return agent;
|
|
71
|
+
});
|
|
72
|
+
const client = createMockStigmer({ getDefault });
|
|
73
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
74
|
+
wrapper: wrapper(client),
|
|
75
|
+
});
|
|
76
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
77
|
+
expect(callCount).toBe(1);
|
|
78
|
+
act(() => result.current.refetch());
|
|
79
|
+
await waitFor(() => expect(callCount).toBe(2), { timeout: 10_000 });
|
|
80
|
+
}, 15_000);
|
|
81
|
+
describe("waitForResolution", () => {
|
|
82
|
+
it("resolves immediately when agent is already loaded", async () => {
|
|
83
|
+
const agent = { metadata: { id: "agt-1" }, status: { defaultInstanceId: "ain-1" } };
|
|
84
|
+
const getDefault = vi.fn().mockResolvedValue(agent);
|
|
85
|
+
const client = createMockStigmer({ getDefault });
|
|
86
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
87
|
+
wrapper: wrapper(client),
|
|
88
|
+
});
|
|
89
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
90
|
+
const resolved = await result.current.waitForResolution();
|
|
91
|
+
expect(resolved).toBe(agent);
|
|
92
|
+
});
|
|
93
|
+
it("awaits and resolves when fetch completes", async () => {
|
|
94
|
+
let resolveExternal;
|
|
95
|
+
const fetchPromise = new Promise((res) => { resolveExternal = res; });
|
|
96
|
+
const getDefault = vi.fn().mockReturnValue(fetchPromise);
|
|
97
|
+
const client = createMockStigmer({ getDefault });
|
|
98
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
99
|
+
wrapper: wrapper(client),
|
|
76
100
|
});
|
|
77
101
|
expect(result.current.isLoading).toBe(true);
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
finally {
|
|
92
|
-
vi.useRealTimers();
|
|
93
|
-
}
|
|
94
|
-
});
|
|
95
|
-
it("surfaces the error after exhausting retries", async () => {
|
|
96
|
-
vi.useFakeTimers();
|
|
97
|
-
try {
|
|
98
|
-
getDefaultMock
|
|
99
|
-
.mockRejectedValueOnce(new Error("fail 1"))
|
|
100
|
-
.mockRejectedValueOnce(new Error("fail 2"));
|
|
101
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
102
|
-
wrapper: makeWrapper(client),
|
|
103
|
-
});
|
|
104
|
-
// Flush first attempt + advance past retry delay + flush retry.
|
|
105
|
-
await act(async () => {
|
|
106
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
107
|
-
});
|
|
108
|
-
await act(async () => {
|
|
109
|
-
await vi.advanceTimersByTimeAsync(1_100);
|
|
110
|
-
});
|
|
111
|
-
expect(result.current.isLoading).toBe(false);
|
|
112
|
-
expect(result.current.agent).toBeNull();
|
|
113
|
-
expect(result.current.error).toBeInstanceOf(Error);
|
|
114
|
-
expect(result.current.error.message).toBe("fail 2");
|
|
115
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(2);
|
|
116
|
-
}
|
|
117
|
-
finally {
|
|
118
|
-
vi.useRealTimers();
|
|
119
|
-
}
|
|
120
|
-
});
|
|
121
|
-
// -----------------------------------------------------------------------
|
|
122
|
-
// Visibility-aware refetch
|
|
123
|
-
// -----------------------------------------------------------------------
|
|
124
|
-
it("refetches when document becomes visible after stale threshold", async () => {
|
|
125
|
-
vi.useFakeTimers();
|
|
126
|
-
try {
|
|
127
|
-
const agent1 = fakeAgent("inst_old");
|
|
128
|
-
const agent2 = fakeAgent("inst_new");
|
|
129
|
-
getDefaultMock
|
|
130
|
-
.mockResolvedValueOnce(agent1)
|
|
131
|
-
.mockResolvedValueOnce(agent2);
|
|
132
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
133
|
-
wrapper: makeWrapper(client),
|
|
134
|
-
});
|
|
135
|
-
// Flush initial fetch.
|
|
136
|
-
await act(async () => {
|
|
137
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
138
|
-
});
|
|
139
|
-
expect(result.current.agent).toBe(agent1);
|
|
140
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(1);
|
|
141
|
-
// Simulate idle period longer than the stale threshold.
|
|
142
|
-
await act(async () => {
|
|
143
|
-
await vi.advanceTimersByTimeAsync(STALE_THRESHOLD_MS + 1_000);
|
|
144
|
-
});
|
|
145
|
-
// Simulate app coming back to foreground.
|
|
146
|
-
act(() => {
|
|
147
|
-
fireVisibilityChange("visible");
|
|
148
|
-
});
|
|
149
|
-
// Flush the refetch.
|
|
150
|
-
await act(async () => {
|
|
151
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
152
|
-
});
|
|
153
|
-
expect(result.current.agent).toBe(agent2);
|
|
154
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(2);
|
|
155
|
-
}
|
|
156
|
-
finally {
|
|
157
|
-
vi.useRealTimers();
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
it("does NOT refetch when visible within the stale window", async () => {
|
|
161
|
-
vi.useFakeTimers();
|
|
162
|
-
try {
|
|
163
|
-
const agent = fakeAgent("inst_fresh");
|
|
164
|
-
getDefaultMock.mockResolvedValueOnce(agent);
|
|
165
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
166
|
-
wrapper: makeWrapper(client),
|
|
167
|
-
});
|
|
168
|
-
// Flush initial fetch.
|
|
169
|
-
await act(async () => {
|
|
170
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
171
|
-
});
|
|
172
|
-
expect(result.current.agent).toBe(agent);
|
|
173
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(1);
|
|
174
|
-
// Only a short time passes — well within stale threshold.
|
|
175
|
-
await act(async () => {
|
|
176
|
-
await vi.advanceTimersByTimeAsync(5_000);
|
|
177
|
-
});
|
|
178
|
-
act(() => {
|
|
179
|
-
fireVisibilityChange("visible");
|
|
180
|
-
});
|
|
181
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(1);
|
|
182
|
-
}
|
|
183
|
-
finally {
|
|
184
|
-
vi.useRealTimers();
|
|
185
|
-
}
|
|
186
|
-
});
|
|
187
|
-
it("does not refetch on hidden event", async () => {
|
|
188
|
-
vi.useFakeTimers();
|
|
189
|
-
try {
|
|
190
|
-
const agent = fakeAgent("inst_1");
|
|
191
|
-
getDefaultMock.mockResolvedValueOnce(agent);
|
|
192
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
193
|
-
wrapper: makeWrapper(client),
|
|
194
|
-
});
|
|
195
|
-
// Flush initial fetch.
|
|
196
|
-
await act(async () => {
|
|
197
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
198
|
-
});
|
|
199
|
-
expect(result.current.agent).toBe(agent);
|
|
200
|
-
// Advance well past stale threshold.
|
|
201
|
-
await act(async () => {
|
|
202
|
-
await vi.advanceTimersByTimeAsync(STALE_THRESHOLD_MS + 1_000);
|
|
203
|
-
});
|
|
204
|
-
// Hidden (not visible) should not trigger refetch.
|
|
205
|
-
act(() => {
|
|
206
|
-
fireVisibilityChange("hidden");
|
|
207
|
-
});
|
|
208
|
-
expect(getDefaultMock).toHaveBeenCalledTimes(1);
|
|
209
|
-
}
|
|
210
|
-
finally {
|
|
211
|
-
vi.useRealTimers();
|
|
212
|
-
}
|
|
213
|
-
});
|
|
214
|
-
// -----------------------------------------------------------------------
|
|
215
|
-
// Manual refetch
|
|
216
|
-
// -----------------------------------------------------------------------
|
|
217
|
-
it("recovers via manual refetch after initial failure", async () => {
|
|
218
|
-
vi.useFakeTimers();
|
|
219
|
-
try {
|
|
220
|
-
const agent = fakeAgent("inst_recovered");
|
|
221
|
-
getDefaultMock
|
|
222
|
-
.mockRejectedValueOnce(new Error("initial fail"))
|
|
223
|
-
.mockRejectedValueOnce(new Error("retry fail"))
|
|
224
|
-
.mockResolvedValueOnce(agent);
|
|
225
|
-
const { result } = renderHook(() => useDefaultAgent("acme"), {
|
|
226
|
-
wrapper: makeWrapper(client),
|
|
227
|
-
});
|
|
228
|
-
// Exhaust initial attempt + retry.
|
|
229
|
-
await act(async () => {
|
|
230
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
231
|
-
});
|
|
232
|
-
await act(async () => {
|
|
233
|
-
await vi.advanceTimersByTimeAsync(1_100);
|
|
234
|
-
});
|
|
235
|
-
expect(result.current.error).not.toBeNull();
|
|
236
|
-
// Manual refetch triggers recovery.
|
|
237
|
-
act(() => {
|
|
238
|
-
result.current.refetch();
|
|
239
|
-
});
|
|
240
|
-
// Flush the refetch.
|
|
241
|
-
await act(async () => {
|
|
242
|
-
await vi.advanceTimersByTimeAsync(0);
|
|
102
|
+
const waitPromise = result.current.waitForResolution();
|
|
103
|
+
const agent = { metadata: { id: "agt-1" }, status: { defaultInstanceId: "ain-1" } };
|
|
104
|
+
resolveExternal(agent);
|
|
105
|
+
await waitFor(() => expect(result.current.isLoading).toBe(false));
|
|
106
|
+
const resolved = await waitPromise;
|
|
107
|
+
expect(resolved).toBe(agent);
|
|
108
|
+
});
|
|
109
|
+
it("rejects when fetch fails", async () => {
|
|
110
|
+
const apiError = new Error("Service unavailable");
|
|
111
|
+
const getDefault = vi.fn().mockRejectedValue(apiError);
|
|
112
|
+
const client = createMockStigmer({ getDefault });
|
|
113
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
114
|
+
wrapper: wrapper(client),
|
|
243
115
|
});
|
|
244
|
-
expect(result.current.
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
116
|
+
expect(result.current.isLoading).toBe(true);
|
|
117
|
+
const waitPromise = result.current.waitForResolution();
|
|
118
|
+
// Prevent unhandled rejection warning — assertion below verifies the value
|
|
119
|
+
waitPromise.catch(() => { });
|
|
120
|
+
await waitFor(() => expect(result.current.error).toBeTruthy(), { timeout: 10_000 });
|
|
121
|
+
await expect(waitPromise).rejects.toThrow("Service unavailable");
|
|
122
|
+
}, 15_000);
|
|
123
|
+
it("rejects immediately when error is already set", async () => {
|
|
124
|
+
const apiError = new Error("Already failed");
|
|
125
|
+
const getDefault = vi.fn().mockRejectedValue(apiError);
|
|
126
|
+
const client = createMockStigmer({ getDefault });
|
|
127
|
+
const { result } = renderHook(() => useDefaultAgent("test-org"), {
|
|
128
|
+
wrapper: wrapper(client),
|
|
129
|
+
});
|
|
130
|
+
await waitFor(() => expect(result.current.error).toBeTruthy(), { timeout: 10_000 });
|
|
131
|
+
await expect(result.current.waitForResolution()).rejects.toThrow("Already failed");
|
|
132
|
+
}, 15_000);
|
|
250
133
|
});
|
|
251
134
|
});
|
|
252
135
|
//# sourceMappingURL=useDefaultAgent.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDefaultAgent.test.js","sourceRoot":"","sources":["../../../src/agent/__tests__/useDefaultAgent.test.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"useDefaultAgent.test.js","sourceRoot":"","sources":["../../../src/agent/__tests__/useDefaultAgent.test.tsx"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,15 @@ export interface UseDefaultAgentReturn {
|
|
|
11
11
|
readonly error: Error | null;
|
|
12
12
|
/** Discard cached data and re-fetch the default agent from the server. */
|
|
13
13
|
readonly refetch: () => void;
|
|
14
|
+
/**
|
|
15
|
+
* Returns a promise that resolves with the Agent once the in-flight
|
|
16
|
+
* fetch settles. If the agent is already loaded, resolves immediately.
|
|
17
|
+
* If the fetch has already failed, rejects immediately.
|
|
18
|
+
*
|
|
19
|
+
* Use this to await the default agent in async flows (e.g. submit)
|
|
20
|
+
* instead of failing when `isLoading` is still true.
|
|
21
|
+
*/
|
|
22
|
+
readonly waitForResolution: () => Promise<Agent>;
|
|
14
23
|
}
|
|
15
24
|
/**
|
|
16
25
|
* Data hook that fetches the platform's default agent.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDefaultAgent.d.ts","sourceRoot":"","sources":["../../src/agent/useDefaultAgent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAehF,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"useDefaultAgent.d.ts","sourceRoot":"","sources":["../../src/agent/useDefaultAgent.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oDAAoD,CAAC;AAehF,+CAA+C;AAC/C,MAAM,WAAW,qBAAqB;IACpC,uEAAuE;IACvE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,gEAAgE;IAChE,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,8EAA8E;IAC9E,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAC7B,0EAA0E;IAC1E,QAAQ,CAAC,OAAO,EAAE,MAAM,IAAI,CAAC;IAC7B;;;;;;;OAOG;IACH,QAAQ,CAAC,iBAAiB,EAAE,MAAM,OAAO,CAAC,KAAK,CAAC,CAAC;CAClD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,qBAAqB,CA+DzE"}
|
package/agent/useDefaultAgent.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useEffect, useRef } from "react";
|
|
2
|
+
import { useCallback, useEffect, useRef } from "react";
|
|
3
3
|
import { create } from "@bufbuild/protobuf";
|
|
4
4
|
import { GetDefaultAgentRequestSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/io_pb";
|
|
5
5
|
import { useStigmer } from "../hooks";
|
|
@@ -45,6 +45,30 @@ export function useDefaultAgent(org) {
|
|
|
45
45
|
}
|
|
46
46
|
: null;
|
|
47
47
|
const { data: agent, isLoading, isRefetching, error, refetch } = useFetch(fetchFn, [org, stigmer], null);
|
|
48
|
+
// Deferred pattern: allows callers to await the in-flight fetch.
|
|
49
|
+
const deferredRef = useRef(null);
|
|
50
|
+
useEffect(() => {
|
|
51
|
+
if (agent && deferredRef.current) {
|
|
52
|
+
deferredRef.current.resolve(agent);
|
|
53
|
+
deferredRef.current = null;
|
|
54
|
+
}
|
|
55
|
+
}, [agent]);
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
if (error && deferredRef.current) {
|
|
58
|
+
deferredRef.current.reject(error);
|
|
59
|
+
deferredRef.current = null;
|
|
60
|
+
}
|
|
61
|
+
}, [error]);
|
|
62
|
+
const waitForResolution = useCallback(() => {
|
|
63
|
+
if (agent)
|
|
64
|
+
return Promise.resolve(agent);
|
|
65
|
+
if (error)
|
|
66
|
+
return Promise.reject(error);
|
|
67
|
+
if (!deferredRef.current) {
|
|
68
|
+
deferredRef.current = createDeferred();
|
|
69
|
+
}
|
|
70
|
+
return deferredRef.current.promise;
|
|
71
|
+
}, [agent, error]);
|
|
48
72
|
useEffect(() => {
|
|
49
73
|
if (typeof document === "undefined")
|
|
50
74
|
return;
|
|
@@ -58,11 +82,17 @@ export function useDefaultAgent(org) {
|
|
|
58
82
|
document.addEventListener("visibilitychange", onVisible);
|
|
59
83
|
return () => document.removeEventListener("visibilitychange", onVisible);
|
|
60
84
|
}, [refetch]);
|
|
61
|
-
return { agent, isLoading, isRefetching, error, refetch };
|
|
85
|
+
return { agent, isLoading, isRefetching, error, refetch, waitForResolution };
|
|
86
|
+
}
|
|
87
|
+
function createDeferred() {
|
|
88
|
+
let resolve;
|
|
89
|
+
let reject;
|
|
90
|
+
const promise = new Promise((res, rej) => {
|
|
91
|
+
resolve = res;
|
|
92
|
+
reject = rej;
|
|
93
|
+
});
|
|
94
|
+
return { promise, resolve, reject };
|
|
62
95
|
}
|
|
63
|
-
// ---------------------------------------------------------------------------
|
|
64
|
-
// Internal helpers
|
|
65
|
-
// ---------------------------------------------------------------------------
|
|
66
96
|
/**
|
|
67
97
|
* Retries `fn` up to `retries` times with a fixed delay between attempts.
|
|
68
98
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useDefaultAgent.js","sourceRoot":"","sources":["../../src/agent/useDefaultAgent.ts"],"names":[],"mappings":"AAAA,YAAY,CAAC;AAEb,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useDefaultAgent.js","sourceRoot":"","sources":["../../src/agent/useDefaultAgent.ts"],"names":[],"mappings":"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"}
|