@iloveagents/foundry-web-shell 0.10.1 → 0.11.1
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/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/load-chat-config.d.ts +13 -1
- package/dist/load-chat-config.js +32 -4
- package/dist/shell-app.d.ts +0 -6
- package/dist/shell-app.js +22 -7
- package/package.json +4 -4
package/dist/index.d.ts
CHANGED
|
@@ -4,5 +4,6 @@ export { ShellLayout } from "./shell-layout.js";
|
|
|
4
4
|
export { defaultAuthAdapter, ShellAuth } from "./auth-default.js";
|
|
5
5
|
export { defaultAgentFetch } from "./service-fetch-default.js";
|
|
6
6
|
export { runtimeConfig } from "./runtime-config.js";
|
|
7
|
+
export { refreshChatConfig } from "./load-chat-config.js";
|
|
7
8
|
export { defineChatModule } from "./types.js";
|
|
8
9
|
export type { ChatModule, ChatConversationConfig, ShellPage, AuthAdapter, BootstrapShellOptions, } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,5 @@ export { ShellLayout } from "./shell-layout.js";
|
|
|
4
4
|
export { defaultAuthAdapter, ShellAuth } from "./auth-default.js";
|
|
5
5
|
export { defaultAgentFetch } from "./service-fetch-default.js";
|
|
6
6
|
export { runtimeConfig } from "./runtime-config.js";
|
|
7
|
+
export { refreshChatConfig } from "./load-chat-config.js";
|
|
7
8
|
export { defineChatModule } from "./types.js";
|
|
@@ -16,4 +16,16 @@
|
|
|
16
16
|
* shells inject their own via the same `agentFetch` seam as the rest of the
|
|
17
17
|
* shell.
|
|
18
18
|
*/
|
|
19
|
-
export declare function loadChatConfig(fetchImpl: typeof fetch): Promise<void>;
|
|
19
|
+
export declare function loadChatConfig(fetchImpl: typeof fetch, params?: Record<string, string>): Promise<void>;
|
|
20
|
+
/** Wired by ShellApp at boot; refreshChatConfig is a no-op before that. */
|
|
21
|
+
export declare function _setChatConfigFetch(fetchImpl: typeof fetch): void;
|
|
22
|
+
/**
|
|
23
|
+
* Re-ask the backend what `Auto` resolves to, optionally for a context.
|
|
24
|
+
*
|
|
25
|
+
* Host apps call this when the user's context changes (e.g. switching
|
|
26
|
+
* workspace) with opaque query params the backend understands — this
|
|
27
|
+
* package deliberately knows nothing about what the params mean. Before
|
|
28
|
+
* the shell has booted there is no fetch client yet; calling then is a
|
|
29
|
+
* safe no-op and the boot-time load will run anyway.
|
|
30
|
+
*/
|
|
31
|
+
export declare function refreshChatConfig(params?: Record<string, string>): Promise<void>;
|
package/dist/load-chat-config.js
CHANGED
|
@@ -18,20 +18,28 @@ const VALID = ["low", "medium", "high", "xhigh"];
|
|
|
18
18
|
* shells inject their own via the same `agentFetch` seam as the rest of the
|
|
19
19
|
* shell.
|
|
20
20
|
*/
|
|
21
|
-
export async function loadChatConfig(fetchImpl) {
|
|
21
|
+
export async function loadChatConfig(fetchImpl, params) {
|
|
22
22
|
const reset = () => reasoningDefaultStore.getState().setResolved(null);
|
|
23
23
|
try {
|
|
24
|
-
const
|
|
24
|
+
const query = params && Object.keys(params).length > 0
|
|
25
|
+
? `?${new URLSearchParams(params)}`
|
|
26
|
+
: "";
|
|
27
|
+
const response = await fetchImpl(`/api/chat/config${query}`);
|
|
25
28
|
if (!response.ok) {
|
|
26
29
|
reset();
|
|
27
30
|
return;
|
|
28
31
|
}
|
|
29
32
|
const body = (await response.json());
|
|
30
33
|
const effort = body?.reasoning?.defaultEffort;
|
|
34
|
+
const scope = body?.reasoning?.scope;
|
|
31
35
|
// `null` is meaningful (reasoning switched off) and anything unrecognised
|
|
32
|
-
// is treated the same as unknown — neither is coerced into a level.
|
|
36
|
+
// is treated the same as unknown — neither is coerced into a level. The
|
|
37
|
+
// scope is the backend's phrase for WHERE the level came from ("for this
|
|
38
|
+
// workspace"); non-string scopes are dropped, never rendered.
|
|
33
39
|
if (typeof effort === "string" && VALID.includes(effort)) {
|
|
34
|
-
reasoningDefaultStore
|
|
40
|
+
reasoningDefaultStore
|
|
41
|
+
.getState()
|
|
42
|
+
.setResolved(effort, typeof scope === "string" && scope ? scope : null);
|
|
35
43
|
}
|
|
36
44
|
else {
|
|
37
45
|
reset();
|
|
@@ -41,3 +49,23 @@ export async function loadChatConfig(fetchImpl) {
|
|
|
41
49
|
reset();
|
|
42
50
|
}
|
|
43
51
|
}
|
|
52
|
+
// --- context-aware refresh -------------------------------------------------
|
|
53
|
+
let bootFetch = null;
|
|
54
|
+
/** Wired by ShellApp at boot; refreshChatConfig is a no-op before that. */
|
|
55
|
+
export function _setChatConfigFetch(fetchImpl) {
|
|
56
|
+
bootFetch = fetchImpl;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Re-ask the backend what `Auto` resolves to, optionally for a context.
|
|
60
|
+
*
|
|
61
|
+
* Host apps call this when the user's context changes (e.g. switching
|
|
62
|
+
* workspace) with opaque query params the backend understands — this
|
|
63
|
+
* package deliberately knows nothing about what the params mean. Before
|
|
64
|
+
* the shell has booted there is no fetch client yet; calling then is a
|
|
65
|
+
* safe no-op and the boot-time load will run anyway.
|
|
66
|
+
*/
|
|
67
|
+
export async function refreshChatConfig(params) {
|
|
68
|
+
if (!bootFetch)
|
|
69
|
+
return;
|
|
70
|
+
await loadChatConfig(bootFetch, params);
|
|
71
|
+
}
|
package/dist/shell-app.d.ts
CHANGED
|
@@ -8,11 +8,5 @@ interface ShellAppProps {
|
|
|
8
8
|
/** Test seam — overrides defaultAgentFetch. */
|
|
9
9
|
agentFetch?: typeof fetch;
|
|
10
10
|
}
|
|
11
|
-
/**
|
|
12
|
-
* Inner shell component — pure React (no `createRoot`). Imported by
|
|
13
|
-
* `bootstrap-shell.tsx` for production and by `__tests__/` for assertions.
|
|
14
|
-
*
|
|
15
|
-
* Wrapper ordering is contractual; see `wrapper-order.test.tsx`.
|
|
16
|
-
*/
|
|
17
11
|
export declare function ShellApp({ modules, pages, baseThemeLayers, authProvider, agentFetch, }: ShellAppProps): import("react/jsx-runtime").JSX.Element;
|
|
18
12
|
export {};
|
package/dist/shell-app.js
CHANGED
|
@@ -5,21 +5,36 @@ import { AGUIRuntimeProvider } from "@iloveagents/foundry-web-ui";
|
|
|
5
5
|
import { ShellAuth } from "./auth-default.js";
|
|
6
6
|
import { ShellLayout } from "./shell-layout.js";
|
|
7
7
|
import { defaultAgentFetch } from "./service-fetch-default.js";
|
|
8
|
-
import { loadChatConfig } from "./load-chat-config.js";
|
|
8
|
+
import { _setChatConfigFetch, loadChatConfig } from "./load-chat-config.js";
|
|
9
9
|
/**
|
|
10
10
|
* Inner shell component — pure React (no `createRoot`). Imported by
|
|
11
11
|
* `bootstrap-shell.tsx` for production and by `__tests__/` for assertions.
|
|
12
12
|
*
|
|
13
13
|
* Wrapper ordering is contractual; see `wrapper-order.test.tsx`.
|
|
14
14
|
*/
|
|
15
|
+
/**
|
|
16
|
+
* Loads the chat config once, from INSIDE the authenticated subtree.
|
|
17
|
+
*
|
|
18
|
+
* This must not run in `ShellApp`'s own body: `ShellAuth` is its CHILD, so
|
|
19
|
+
* an effect there fires before sign-in completes. The agent fetch would
|
|
20
|
+
* then 401, exhaust its refresh retry, and call
|
|
21
|
+
* `recoverFromHardAuthFailure` -> `loginRedirect` -> remount -> repeat: an
|
|
22
|
+
* infinite login loop on any session that isn't already cached. Rendering
|
|
23
|
+
* the load here means there is a token by the time it runs.
|
|
24
|
+
*/
|
|
25
|
+
function ChatConfigBoot({ fetchImpl }) {
|
|
26
|
+
useEffect(() => {
|
|
27
|
+
void loadChatConfig(fetchImpl);
|
|
28
|
+
}, [fetchImpl]);
|
|
29
|
+
return null;
|
|
30
|
+
}
|
|
15
31
|
export function ShellApp({ modules, pages, baseThemeLayers, authProvider, agentFetch, }) {
|
|
16
|
-
// Ask the backend what `Auto` currently resolves to, so the composer's
|
|
17
|
-
// effort picker can name the level instead of leaving the user guessing.
|
|
18
|
-
// Uses the same agentFetch seam as everything else (auth, base URL, test
|
|
19
|
-
// override); failure resets the level to unknown and the picker says so.
|
|
20
32
|
const resolvedAgentFetch = agentFetch ?? defaultAgentFetch;
|
|
33
|
+
// Bind the refresh seam here (cheap, no I/O) so a host-app context
|
|
34
|
+
// refresh that races boot uses the same fetch client. The actual load
|
|
35
|
+
// happens in <ChatConfigBoot> INSIDE ShellAuth — see the note there.
|
|
21
36
|
useEffect(() => {
|
|
22
|
-
|
|
37
|
+
_setChatConfigFetch(resolvedAgentFetch);
|
|
23
38
|
}, [resolvedAgentFetch]);
|
|
24
39
|
// Merge module pages with customer pages — customer wins on path collision
|
|
25
40
|
// (last-wins). Stable order: customer pages first (they appear in Routes
|
|
@@ -57,7 +72,7 @@ export function ShellApp({ modules, pages, baseThemeLayers, authProvider, agentF
|
|
|
57
72
|
// Aggregate chatConversation configs from all modules. First-match
|
|
58
73
|
// wins at URL-match time (rare to have more than one anyway).
|
|
59
74
|
const chatConversationConfigs = useMemo(() => modules.flatMap((m) => (m.chatConversation ? [m.chatConversation] : [])), [modules]);
|
|
60
|
-
return (_jsx(BrowserRouter, { children:
|
|
75
|
+
return (_jsx(BrowserRouter, { children: _jsxs(ShellAuth, { adapter: authProvider, children: [_jsx(ChatConfigBoot, { fetchImpl: resolvedAgentFetch }), _jsx(ComposedWrappers, { wrappers: wrappers, children: _jsx(ChatConversationAwareRuntime, { fetchFn: fetchFn, configs: chatConversationConfigs, toolUIs: toolUIs, children: _jsx(Suspense, { fallback: null, children: _jsx(Routes, { children: _jsx(Route, { element: _jsx(ShellLayout, { modules: modules, baseThemeLayers: baseThemeLayers }), children: mergedPages.map((p) => (_jsx(Route, { path: p.path === "/" ? undefined : p.path, index: p.path === "/", element: p.element }, p.path))) }) }) }) }) })] }) }));
|
|
61
76
|
}
|
|
62
77
|
/**
|
|
63
78
|
* Reads the current pathname (only meaningful inside ``<BrowserRouter>``),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@iloveagents/foundry-web-shell",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "Browser bootstrap and layout shell for Foundry UI — bootstrapShell({ modules, pages, theme, authProvider }) mounts the SPA around foundry-web-ui. Module-agnostic.",
|
|
6
6
|
"keywords": [
|
|
@@ -45,9 +45,9 @@
|
|
|
45
45
|
"zustand": "^5.0.0"
|
|
46
46
|
},
|
|
47
47
|
"dependencies": {
|
|
48
|
-
"@iloveagents/foundry-agent": "^0.
|
|
49
|
-
"@iloveagents/foundry-web-ui": "^0.
|
|
50
|
-
"@iloveagents/foundry-web-primitives": "^0.
|
|
48
|
+
"@iloveagents/foundry-agent": "^0.11.1",
|
|
49
|
+
"@iloveagents/foundry-web-ui": "^0.11.1",
|
|
50
|
+
"@iloveagents/foundry-web-primitives": "^0.11.1"
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
53
|
"@assistant-ui/react": "^0.15.1",
|