@streamoid/agent 0.6.14 → 0.6.16
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 +54 -0
- package/dist/index.js +124 -57
- package/dist/style.css +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -33,6 +33,34 @@ export interface AgentChatShellWorkspace {
|
|
|
33
33
|
[key: string]: unknown;
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
+
/** What the host reports about the page the panel is sitting on. Unknown keys
|
|
37
|
+
* are dropped server-side, so hosts may add their own freely. */
|
|
38
|
+
export interface AgentHostContext {
|
|
39
|
+
/** Which application, e.g. `artifax`. */
|
|
40
|
+
app?: string;
|
|
41
|
+
/** Human name of the current page, e.g. `Boards`. */
|
|
42
|
+
page?: string;
|
|
43
|
+
/** Route pattern rather than the filled path, e.g. `/dashboard/:workspaceId/home`. */
|
|
44
|
+
route?: string;
|
|
45
|
+
/** Absolute URL of the host page. */
|
|
46
|
+
url?: string;
|
|
47
|
+
/** Identifiers a tool call might need: workspaceId, boardId, sessionId… */
|
|
48
|
+
ids?: Record<string, string | number>;
|
|
49
|
+
/** A short list of what is on screen — board names, selected items. */
|
|
50
|
+
visible?: string[];
|
|
51
|
+
[key: string]: unknown;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Whether the panel currently needs the host's whole screen, and why. */
|
|
55
|
+
export interface AgentSurfaceState {
|
|
56
|
+
/** `fullscreen` while the conversation on screen has an artefact panel open. */
|
|
57
|
+
mode: 'inline' | 'fullscreen';
|
|
58
|
+
/** How many panels that conversation has open. */
|
|
59
|
+
panelCount: number;
|
|
60
|
+
/** The panel in front, when there is one. */
|
|
61
|
+
activePanel?: { id: string; kind: string; title: string } | null;
|
|
62
|
+
}
|
|
63
|
+
|
|
36
64
|
export interface AgentChatShellAdapters {
|
|
37
65
|
auth: AgentChatShellAuth;
|
|
38
66
|
workspace: { current: AgentChatShellWorkspace };
|
|
@@ -40,6 +68,13 @@ export interface AgentChatShellAdapters {
|
|
|
40
68
|
config: {
|
|
41
69
|
apiBase: string;
|
|
42
70
|
hide?: { sidepane?: boolean; newBrief?: boolean; notifications?: boolean };
|
|
71
|
+
/**
|
|
72
|
+
* `inline_ask` declares this mount an inline assistant sitting on top of a
|
|
73
|
+
* host application page. It unlocks the tools that only make sense there —
|
|
74
|
+
* `capture_inline_screenshot`, `navigate_parent` — and adds the inline-mode
|
|
75
|
+
* instructions to the prompt. Defaults to `normal`.
|
|
76
|
+
*/
|
|
77
|
+
widgetMode?: 'normal' | 'inline_ask';
|
|
43
78
|
};
|
|
44
79
|
navigation: {
|
|
45
80
|
chatId: string | null;
|
|
@@ -48,6 +83,25 @@ export interface AgentChatShellAdapters {
|
|
|
48
83
|
/** Backend recovered after an outage — host decides what to do (must NOT
|
|
49
84
|
* reload the host window). */
|
|
50
85
|
onBackendRecovered?: () => void;
|
|
86
|
+
/**
|
|
87
|
+
* The page the panel is sitting on. Sent with every message, so update it as
|
|
88
|
+
* the user navigates: the agent then knows where they are without spending a
|
|
89
|
+
* turn on `capture_inline_screenshot`.
|
|
90
|
+
*/
|
|
91
|
+
hostContext?: AgentHostContext | null;
|
|
92
|
+
/**
|
|
93
|
+
* Called when the panel starts or stops showing a non-text artefact — a
|
|
94
|
+
* table, an image set, a widget, a techpack, a board.
|
|
95
|
+
*
|
|
96
|
+
* The panel cannot give an artefact more room than the host gave the panel,
|
|
97
|
+
* and a rail wide enough for a conversation is not wide enough for a
|
|
98
|
+
* spreadsheet. So the decision is reported rather than taken: widen your
|
|
99
|
+
* container on `fullscreen` and restore it on `inline`. Do nothing and
|
|
100
|
+
* behaviour is unchanged.
|
|
101
|
+
*
|
|
102
|
+
* Fires only on change, and only for the conversation on screen.
|
|
103
|
+
*/
|
|
104
|
+
onSurfaceChange?: (state: AgentSurfaceState) => void;
|
|
51
105
|
/**
|
|
52
106
|
* Supply the canvas as a component and the Dreamer panel drops its iframe:
|
|
53
107
|
* no embedded page, so no cross-origin auth, no postMessage handshake, no
|
package/dist/index.js
CHANGED
|
@@ -15205,6 +15205,7 @@ const trimTrailingSlashes = (e) => "".replace(/\/+$/, ""), DEFAULT_API_BASE = tr
|
|
|
15205
15205
|
mode: "unknown",
|
|
15206
15206
|
widgetMode: "normal",
|
|
15207
15207
|
inlineCollapsed: !1,
|
|
15208
|
+
hostContext: null,
|
|
15208
15209
|
setAuth: (t) => e(() => (storeWorkspaceId(t.workspaceId), {
|
|
15209
15210
|
encToken: t.encToken || null,
|
|
15210
15211
|
workspaceId: t.workspaceId,
|
|
@@ -15230,11 +15231,25 @@ const trimTrailingSlashes = (e) => "".replace(/\/+$/, ""), DEFAULT_API_BASE = tr
|
|
|
15230
15231
|
setApiBase: (t) => e({ apiBase: t }),
|
|
15231
15232
|
setCentralDashboardUrl: (t) => e({ centralDashboardUrl: t }),
|
|
15232
15233
|
setMode: (t) => e({ mode: t }),
|
|
15233
|
-
|
|
15234
|
-
|
|
15235
|
-
|
|
15236
|
-
|
|
15234
|
+
/* A WRITE THAT CHANGES NOTHING STILL COSTS A RENDER.
|
|
15235
|
+
*
|
|
15236
|
+
* `setWidgetMode` and `setHostContext` are both called from effects the
|
|
15237
|
+
* native shell runs on mount, and hosts that pass neither (every host before
|
|
15238
|
+
* this feature) were therefore paying two store notifications for two no-ops.
|
|
15239
|
+
* Nothing in the store is cheap to notify: `ChatScreen` subscribes to the
|
|
15240
|
+
* WHOLE auth store, so each notification re-renders the transcript.
|
|
15241
|
+
*
|
|
15242
|
+
* Returning the current state object short-circuits zustand's setState
|
|
15243
|
+
* (`Object.is(nextState, state)`), so an unchanged value notifies nobody. */
|
|
15244
|
+
setWidgetMode: (t) => e((n) => {
|
|
15245
|
+
const o = normalizeWidgetMode(t), s = o === "inline_ask";
|
|
15246
|
+
return n.widgetMode === o && n.inlineCollapsed === s ? n : { widgetMode: o, inlineCollapsed: s };
|
|
15247
|
+
}),
|
|
15237
15248
|
setInlineCollapsed: (t) => e({ inlineCollapsed: t }),
|
|
15249
|
+
setHostContext: (t) => e((n) => {
|
|
15250
|
+
const o = t ?? null;
|
|
15251
|
+
return n.hostContext === o || n.hostContext && o && JSON.stringify(n.hostContext) === JSON.stringify(o) ? n : { hostContext: o };
|
|
15252
|
+
}),
|
|
15238
15253
|
refreshToken: (t) => e({ encToken: t }),
|
|
15239
15254
|
clearAuth: () => {
|
|
15240
15255
|
const t = window;
|
|
@@ -15251,6 +15266,7 @@ const trimTrailingSlashes = (e) => "".replace(/\/+$/, ""), DEFAULT_API_BASE = tr
|
|
|
15251
15266
|
hideNewBrief: !1,
|
|
15252
15267
|
hideNotifications: !1,
|
|
15253
15268
|
widgetMode: "normal",
|
|
15269
|
+
hostContext: null,
|
|
15254
15270
|
inlineCollapsed: !1,
|
|
15255
15271
|
ready: !1
|
|
15256
15272
|
});
|
|
@@ -16300,8 +16316,8 @@ async function sendMessageToAgent(e, t, n, o, s, l = !1, c = {}) {
|
|
|
16300
16316
|
enc_token: getEncTokenValue(),
|
|
16301
16317
|
color_mode: useThemeStore.getState().colorMode,
|
|
16302
16318
|
widget_mode: c.widgetMode ?? "normal"
|
|
16303
|
-
};
|
|
16304
|
-
return c.clientMessageId && (f.client_message_id = c.clientMessageId), c.resumeValues !== void 0 ? (f.resume_values = c.resumeValues, f.resume_message = s) : c.resume_values !== void 0 && (f.resume_values = c.resume_values, f.resume_message = s), c.autonomy !== void 0 && (f.autonomy = c.autonomy), c.llmModel && (f.llm_model = c.llmModel), c.agentId && (f.agent_id = c.agentId), await apiFetch(`/workspaces/${e}/conversations/send`, {
|
|
16319
|
+
}, h = useAuthStore.getState().hostContext;
|
|
16320
|
+
return h && Object.keys(h).length > 0 && (f.host_context = h), c.clientMessageId && (f.client_message_id = c.clientMessageId), c.resumeValues !== void 0 ? (f.resume_values = c.resumeValues, f.resume_message = s) : c.resume_values !== void 0 && (f.resume_values = c.resume_values, f.resume_message = s), c.autonomy !== void 0 && (f.autonomy = c.autonomy), c.llmModel && (f.llm_model = c.llmModel), c.agentId && (f.agent_id = c.agentId), await apiFetch(`/workspaces/${e}/conversations/send`, {
|
|
16305
16321
|
method: "POST",
|
|
16306
16322
|
body: JSON.stringify(f)
|
|
16307
16323
|
});
|
|
@@ -128668,67 +128684,76 @@ function buildCanvasScreenshot({
|
|
|
128668
128684
|
width: e,
|
|
128669
128685
|
height: t,
|
|
128670
128686
|
title: n,
|
|
128671
|
-
lines: o
|
|
128687
|
+
lines: o,
|
|
128688
|
+
source: s
|
|
128672
128689
|
}) {
|
|
128673
|
-
const
|
|
128674
|
-
|
|
128675
|
-
const
|
|
128676
|
-
if (!
|
|
128690
|
+
const l = document.createElement("canvas");
|
|
128691
|
+
l.width = e, l.height = t;
|
|
128692
|
+
const c = l.getContext("2d");
|
|
128693
|
+
if (!c)
|
|
128677
128694
|
throw new Error("Canvas rendering is not available");
|
|
128678
|
-
const
|
|
128679
|
-
return
|
|
128680
|
-
|
|
128695
|
+
const f = document.documentElement.classList.contains("dark");
|
|
128696
|
+
return c.fillStyle = f ? "#0b0b0f" : "#f6f7fb", c.fillRect(0, 0, e, t), c.fillStyle = f ? "#f5f5f5" : "#111827", c.font = "600 22px sans-serif", c.fillText(n, 24, 42), c.font = "14px sans-serif", c.fillStyle = f ? "#d1d5db" : "#4b5563", o.slice(0, 18).forEach((h, g) => {
|
|
128697
|
+
c.fillText(h.slice(0, 120), 24, 76 + g * 24);
|
|
128681
128698
|
}), {
|
|
128682
|
-
dataUrl:
|
|
128699
|
+
dataUrl: l.toDataURL("image/png"),
|
|
128683
128700
|
width: e,
|
|
128684
128701
|
height: t,
|
|
128685
|
-
source:
|
|
128702
|
+
source: s
|
|
128686
128703
|
};
|
|
128687
128704
|
}
|
|
128705
|
+
function ownDocumentIsHostPage() {
|
|
128706
|
+
return !(window.parent && window.parent !== window);
|
|
128707
|
+
}
|
|
128688
128708
|
async function captureIframeScreenshot() {
|
|
128689
|
-
|
|
128690
|
-
|
|
128691
|
-
|
|
128692
|
-
|
|
128693
|
-
|
|
128694
|
-
|
|
128709
|
+
const e = ownDocumentIsHostPage() ? "host_page" : "widget_iframe";
|
|
128710
|
+
console.info("[UIComponents] Capturing own document screenshot", { source: e });
|
|
128711
|
+
const t = Math.max(1, Math.ceil(window.innerWidth || 1024)), n = Math.max(1, Math.ceil(window.innerHeight || 768)), o = document.documentElement.cloneNode(!0);
|
|
128712
|
+
o.querySelectorAll("script").forEach((h) => h.remove()), o.setAttribute("xmlns", "http://www.w3.org/1999/xhtml");
|
|
128713
|
+
const s = new XMLSerializer().serializeToString(o), l = `
|
|
128714
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="${t}" height="${n}">
|
|
128715
|
+
<foreignObject width="100%" height="100%">${s}</foreignObject>
|
|
128695
128716
|
</svg>
|
|
128696
|
-
`,
|
|
128717
|
+
`, c = new Blob([l], { type: "image/svg+xml;charset=utf-8" }), f = URL.createObjectURL(c);
|
|
128697
128718
|
try {
|
|
128698
|
-
const
|
|
128699
|
-
const
|
|
128700
|
-
() =>
|
|
128719
|
+
const h = new Image(), g = new Promise((R, T) => {
|
|
128720
|
+
const M = window.setTimeout(
|
|
128721
|
+
() => T(new Error("Widget iframe screenshot timed out")),
|
|
128701
128722
|
2e3
|
|
128702
128723
|
);
|
|
128703
|
-
|
|
128704
|
-
window.clearTimeout(
|
|
128705
|
-
},
|
|
128706
|
-
window.clearTimeout(
|
|
128724
|
+
h.onload = () => {
|
|
128725
|
+
window.clearTimeout(M), R();
|
|
128726
|
+
}, h.onerror = () => {
|
|
128727
|
+
window.clearTimeout(M), T(new Error("Widget iframe screenshot failed to render"));
|
|
128707
128728
|
};
|
|
128708
128729
|
});
|
|
128709
|
-
|
|
128710
|
-
const
|
|
128711
|
-
|
|
128712
|
-
const
|
|
128713
|
-
if (!
|
|
128714
|
-
return
|
|
128715
|
-
dataUrl:
|
|
128716
|
-
width:
|
|
128717
|
-
height:
|
|
128718
|
-
source:
|
|
128730
|
+
h.src = f, await g;
|
|
128731
|
+
const b = document.createElement("canvas");
|
|
128732
|
+
b.width = t, b.height = n;
|
|
128733
|
+
const E = b.getContext("2d");
|
|
128734
|
+
if (!E) throw new Error("Canvas rendering is not available");
|
|
128735
|
+
return E.drawImage(h, 0, 0, t, n), {
|
|
128736
|
+
dataUrl: b.toDataURL("image/png"),
|
|
128737
|
+
width: t,
|
|
128738
|
+
height: n,
|
|
128739
|
+
source: e
|
|
128719
128740
|
};
|
|
128720
|
-
} catch (
|
|
128721
|
-
return console.info("[UIComponents] DOM screenshot fallback failed; using summary canvas",
|
|
128722
|
-
width:
|
|
128723
|
-
height:
|
|
128741
|
+
} catch (h) {
|
|
128742
|
+
return console.info("[UIComponents] DOM screenshot fallback failed; using summary canvas", h), buildCanvasScreenshot({
|
|
128743
|
+
width: t,
|
|
128744
|
+
height: n,
|
|
128724
128745
|
title: document.title || "Copilot Widget",
|
|
128725
128746
|
lines: [
|
|
128726
128747
|
`URL: ${window.location.href}`,
|
|
128727
128748
|
`Visible text: ${(document.body.innerText || "").replace(/\s+/g, " ").trim()}`
|
|
128728
|
-
]
|
|
128749
|
+
],
|
|
128750
|
+
/* Rasterisation failed and this is a canvas with the page's text drawn
|
|
128751
|
+
* onto it. It is not a screenshot, so it does not claim to be one: the
|
|
128752
|
+
* backend declines to describe it as the host page. */
|
|
128753
|
+
source: "summary_canvas"
|
|
128729
128754
|
});
|
|
128730
128755
|
} finally {
|
|
128731
|
-
URL.revokeObjectURL(
|
|
128756
|
+
URL.revokeObjectURL(f);
|
|
128732
128757
|
}
|
|
128733
128758
|
}
|
|
128734
128759
|
async function captureScreenshotWithFallback(e) {
|
|
@@ -128741,7 +128766,7 @@ async function captureScreenshotWithFallback(e) {
|
|
|
128741
128766
|
dataUrl: n.dataUrl,
|
|
128742
128767
|
width: n.width,
|
|
128743
128768
|
height: n.height,
|
|
128744
|
-
source: n.source || "host_page"
|
|
128769
|
+
source: n.source === "summary_canvas" || n.source === "widget_iframe" ? n.source : "host_page"
|
|
128745
128770
|
};
|
|
128746
128771
|
} catch (n) {
|
|
128747
128772
|
console.info("[UIComponents] Host screenshot unavailable; falling back to widget iframe capture", n);
|
|
@@ -130329,7 +130354,24 @@ function SidePaneHost({
|
|
|
130329
130354
|
className: [
|
|
130330
130355
|
"shrink-0 rounded-[8px] px-2.5 py-1 text-[13px] leading-[18px] transition-colors",
|
|
130331
130356
|
"outline-none focus-visible:ring-2 focus-visible:ring-[var(--alias-border-focus)]",
|
|
130332
|
-
|
|
130357
|
+
/* SELECTED IS A FILL, NOT A SURFACE.
|
|
130358
|
+
*
|
|
130359
|
+
* This was `surface-subtle`, which is one step lighter than
|
|
130360
|
+
* `surface-base` in the dark theme and therefore read as a
|
|
130361
|
+
* selected tab -- and is `#ffffff` in the LIGHT theme, the
|
|
130362
|
+
* same as the card it sits on, so the highlighted tab was
|
|
130363
|
+
* invisible. Every `--alias-surface-*` token collapses to
|
|
130364
|
+
* white there on purpose: light mode expresses elevation
|
|
130365
|
+
* with shadow and border, which a 24px tab has neither of.
|
|
130366
|
+
*
|
|
130367
|
+
* `fill-neutral-neutralselected` is the design system's
|
|
130368
|
+
* answer for exactly this state and has contrast in both
|
|
130369
|
+
* themes (#242424 on #101010 dark, #ededed on #ffffff
|
|
130370
|
+
* light). Hover on an unselected tab stays a text change:
|
|
130371
|
+
* the light-mode hover fill is DARKER than the selected
|
|
130372
|
+
* fill, so filling on hover would make hover look more
|
|
130373
|
+
* selected than selected. */
|
|
130374
|
+
E ? "bg-[var(--alias-fill-neutral-neutralselected)] text-[var(--alias-text---icons-primary)]" : "text-[var(--alias-text---icons-secondary)] hover:text-[var(--alias-text---icons-primary)]"
|
|
130333
130375
|
].join(" "),
|
|
130334
130376
|
children: b.title
|
|
130335
130377
|
},
|
|
@@ -130346,7 +130388,7 @@ function SidePaneHost({
|
|
|
130346
130388
|
"aria-label": `Close ${h.title}`,
|
|
130347
130389
|
title: `Close ${h.title}`,
|
|
130348
130390
|
"data-testid": "side-pane-close",
|
|
130349
|
-
className: "inline-flex size-8 shrink-0 items-center justify-center rounded-[8px] text-[var(--alias-text---icons-secondary)] transition-colors hover:bg-[var(--alias-
|
|
130391
|
+
className: "inline-flex size-8 shrink-0 items-center justify-center rounded-[8px] text-[var(--alias-text---icons-secondary)] transition-colors hover:bg-[var(--alias-fill-neutral-neutralhover)] hover:text-[var(--alias-text---icons-primary)]",
|
|
130350
130392
|
children: /* @__PURE__ */ jsx(PanelRightClose, { className: "size-4" })
|
|
130351
130393
|
}
|
|
130352
130394
|
)
|
|
@@ -136582,6 +136624,17 @@ function AttentionToast() {
|
|
|
136582
136624
|
n.id
|
|
136583
136625
|
) }) }) : null;
|
|
136584
136626
|
}
|
|
136627
|
+
function deriveSurfaceState(e, t, n) {
|
|
136628
|
+
const o = e.filter((l) => l.chatId === t), s = o.find((l) => l.id === n) ?? o[o.length - 1];
|
|
136629
|
+
return {
|
|
136630
|
+
mode: o.length > 0 ? "fullscreen" : "inline",
|
|
136631
|
+
panelCount: o.length,
|
|
136632
|
+
activePanel: s ? { id: s.id, kind: s.kind, title: s.title } : null
|
|
136633
|
+
};
|
|
136634
|
+
}
|
|
136635
|
+
function surfaceFingerprint(e) {
|
|
136636
|
+
return `${e.mode}:${e.panelCount}:${e.activePanel?.id ?? ""}`;
|
|
136637
|
+
}
|
|
136585
136638
|
function getCentralUrl() {
|
|
136586
136639
|
return useAuthStore.getState().centralDashboardUrl;
|
|
136587
136640
|
}
|
|
@@ -136803,7 +136856,7 @@ function useFetchConversations(e) {
|
|
|
136803
136856
|
function AgentChatShell({ adapters: e }) {
|
|
136804
136857
|
const t = useRef(e);
|
|
136805
136858
|
t.current = e;
|
|
136806
|
-
const { auth: n, workspace: o, theme: s, config: l, navigation: c } = e;
|
|
136859
|
+
const { auth: n, workspace: o, theme: s, config: l, navigation: c } = e, { hostContext: f, onSurfaceChange: h } = e;
|
|
136807
136860
|
useState(() => {
|
|
136808
136861
|
configureStreamAgentClient({
|
|
136809
136862
|
getApiBase: () => t.current.config.apiBase,
|
|
@@ -136812,8 +136865,8 @@ function AgentChatShell({ adapters: e }) {
|
|
|
136812
136865
|
onSessionExpired: () => t.current.auth.onSessionExpired?.(),
|
|
136813
136866
|
onBackendRecovered: () => t.current.onBackendRecovered?.()
|
|
136814
136867
|
});
|
|
136815
|
-
const
|
|
136816
|
-
return
|
|
136868
|
+
const I = useAuthStore.getState();
|
|
136869
|
+
return I.setMode("iframe"), I.setAuth({
|
|
136817
136870
|
workspaceId: o.current.id,
|
|
136818
136871
|
userId: n.user.id,
|
|
136819
136872
|
email: n.user.email,
|
|
@@ -136825,19 +136878,33 @@ function AgentChatShell({ adapters: e }) {
|
|
|
136825
136878
|
totalCredits: o.current.totalCredits ?? null,
|
|
136826
136879
|
hideSidepane: l.hide?.sidepane ?? !0,
|
|
136827
136880
|
hideNewBrief: l.hide?.newBrief ?? !0,
|
|
136828
|
-
hideNotifications: l.hide?.notifications ?? !0
|
|
136829
|
-
|
|
136881
|
+
hideNotifications: l.hide?.notifications ?? !0,
|
|
136882
|
+
widgetMode: l.widgetMode ?? "normal"
|
|
136883
|
+
}), useAuthStore.getState().setHostContext(f ?? null), useThemeStore.getState().setTheme(s.mode), !0;
|
|
136830
136884
|
}), useEffect(() => {
|
|
136831
136885
|
useAuthStore.getState().switchWorkspace(o.current.id);
|
|
136832
136886
|
}, [o.current.id]), useEffect(() => {
|
|
136833
136887
|
useThemeStore.getState().setTheme(s.mode);
|
|
136834
136888
|
}, [s.mode]), useEffect(() => {
|
|
136889
|
+
useAuthStore.getState().setWidgetMode(l.widgetMode ?? "normal");
|
|
136890
|
+
}, [l.widgetMode]), useEffect(() => {
|
|
136891
|
+
useAuthStore.getState().setHostContext(f ?? null);
|
|
136892
|
+
}, [f]), useEffect(() => {
|
|
136835
136893
|
useAuthStore.getState().setCredits(
|
|
136836
136894
|
o.current.availableCredits ?? null,
|
|
136837
136895
|
o.current.totalCredits ?? null
|
|
136838
136896
|
);
|
|
136839
|
-
}, [o.current.availableCredits, o.current.totalCredits])
|
|
136840
|
-
const
|
|
136897
|
+
}, [o.current.availableCredits, o.current.totalCredits]);
|
|
136898
|
+
const g = useChatStore((I) => I.panels), b = useChatStore((I) => I.activePanelId), E = useChatStore((I) => I.activeChatId), R = useMemo(
|
|
136899
|
+
() => deriveSurfaceState(g, E, b),
|
|
136900
|
+
[g, b, E]
|
|
136901
|
+
), T = useRef(null);
|
|
136902
|
+
useEffect(() => {
|
|
136903
|
+
if (!h) return;
|
|
136904
|
+
const I = surfaceFingerprint(R);
|
|
136905
|
+
T.current !== I && (T.current = I, h(R));
|
|
136906
|
+
}, [R, h]), useSessionKeepalive(), useCompletionNotifier(), useFetchConversations(o.current.id);
|
|
136907
|
+
const M = useMemo(
|
|
136841
136908
|
() => ({
|
|
136842
136909
|
chatId: c.chatId,
|
|
136843
136910
|
navigateToChat: c.onChatIdChange
|
|
@@ -136849,7 +136916,7 @@ function AgentChatShell({ adapters: e }) {
|
|
|
136849
136916
|
{
|
|
136850
136917
|
className: "sa-surface relative flex h-full w-full flex-col overflow-hidden bg-transparent text-[var(--alias-text---icons-primary)]",
|
|
136851
136918
|
"data-theme": "Mode 1",
|
|
136852
|
-
children: /* @__PURE__ */ jsx(ChatNavigationProvider, { value:
|
|
136919
|
+
children: /* @__PURE__ */ jsx(ChatNavigationProvider, { value: M, children: /* @__PURE__ */ jsxs(HostCanvasProvider, { value: e.canvas ?? null, children: [
|
|
136853
136920
|
/* @__PURE__ */ jsx(AttentionToast, {}),
|
|
136854
136921
|
/* @__PURE__ */ jsx(ChatScreen, {})
|
|
136855
136922
|
] }) })
|