@astralbeam/sdk 0.6.0 → 0.7.0

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/README.md CHANGED
@@ -28,7 +28,7 @@ const handle = mountAstralBeamChat(document.getElementById("sidebar"), {})
28
28
  - The widget fills its container, so give it a parent with a definite height (`min-h-0` in a flex column).
29
29
  - Two origins by design: chat streams to the hosted cloud by default, while the token comes from your own app's endpoint. Self-hosted deployments set `apiUrl` to their own origin.
30
30
  - `@astralbeam/sdk/client` ships no React; the chat loads as a lazy chunk with its own bundled copy.
31
- - `react` and `react-dom` are optional peer dependencies used only by `@astralbeam/sdk/react`.
31
+ - No runtime dependencies; `react` and `react-dom` are optional peers used only by `@astralbeam/sdk/react`.
32
32
  - Mount it above your router if the transcript should survive page navigation.
33
33
 
34
34
  ## Authentication
@@ -80,7 +80,7 @@ Every option is also a prop on `<AstralBeamChat>`; `handle.update(options)` appl
80
80
 
81
81
  | Option | Default | Meaning |
82
82
  | ------------------------------------ | ---------------------------------- | ------------------------------------------------------------------ |
83
- | `agentId` | organization's default | `agt_<organization>_<agent>` from the dashboard |
83
+ | `agentId` | organization's default | `agent_<uuid>`, copied from the dashboard |
84
84
  | `apiUrl` | `https://app.astralbeam.ai/api` | Base URL of the AstralBeam API; the widget calls `/chat` there |
85
85
  | `fetchChatAuthToken` | `{ url: "/api/astralbeam/token" }` | Chat auth token endpoint as `{ url, ...RequestInit }`, or a minter |
86
86
  | `title`, `showHeader` | `"AstralBeam"`, `true` | Header text, and whether the header and reset button show |
@@ -146,7 +146,6 @@ There is no root export. Conversation history is not built yet.
146
146
  | `@astralbeam/sdk/core` | `createAstralBeamChat`, the headless session | none |
147
147
  | `@astralbeam/sdk/react` | `<AstralBeamChat>`, `useAstralBeamChat` | `react`, `react-dom` |
148
148
  | `@astralbeam/sdk/server` | `createChatAuthToken`, the token minter | none |
149
- | `@astralbeam/sdk/vue` | Vue components (placeholder) | `vue` |
150
149
 
151
150
  Types resolve under every TypeScript module resolution mode, including the classic `"moduleResolution": "node"` that Ionic, Capacitor, and Create React App templates still ship. TypeScript 5.0 or later is required, because the declarations use `const` type parameters; on TypeScript 4.x the `.d.ts` files fail to parse.
152
151
 
package/dist/client.d.ts CHANGED
@@ -130,6 +130,11 @@ interface AstralBeamChatTheme {
130
130
  light?: AstralBeamChatThemeVariables | undefined;
131
131
  dark?: AstralBeamChatThemeVariables | undefined;
132
132
  }
133
+ /**
134
+ * Every option of the drop-in chat widget, and the one documented source the React props and the
135
+ * headless core options are derived from. Each is optional and accepts an explicit `undefined`, so
136
+ * a host with `exactOptionalPropertyTypes` can pass a value it does not have yet.
137
+ */
133
138
  interface MountAstralBeamChatOptions {
134
139
  /**
135
140
  * Public ID of the organization-owned agent. Omit it to use the organization's default agent,
@@ -164,7 +169,7 @@ interface MountAstralBeamChatOptions {
164
169
  /** Host-defined tools the agent can call, executed in the host page, keyed by tool name. */
165
170
  tools?: Record<string, ToolDefinition> | undefined;
166
171
  /** Host-defined widgets the agent can render inline in the conversation, keyed by identifier. */
167
- widgets?: Record<string, WidgetDefinition>;
172
+ widgets?: Record<string, WidgetDefinition> | undefined;
168
173
  /** Host-rendered replacements for parts of the widget's chrome; see `AstralBeamChatSlots`. */
169
174
  slots?: AstralBeamChatSlots | undefined;
170
175
  /**
@@ -179,7 +184,7 @@ interface MountAstralBeamChatOptions {
179
184
  */
180
185
  attachments?: boolean | AstralBeamChatAttachmentOptions | undefined;
181
186
  /** Color scheme of the widget. Default `"system"`. */
182
- colorScheme?: AstralBeamChatColorScheme;
187
+ colorScheme?: AstralBeamChatColorScheme | undefined;
183
188
  /** Custom values for the widget's theming CSS variables, per color scheme. */
184
189
  theme?: AstralBeamChatTheme | undefined;
185
190
  /**
package/dist/client.js CHANGED
@@ -1 +1 @@
1
- import{c as e,t}from"./debug-DyjRg3e0.js";function n(e){return e}function r(e){return e}function i(n,r){let i={...r},a=t(i.debug);a?.(`mount`,`mounting chat widget`,{agentId:i.agentId??`(organization default)`,title:i.title??`AstralBeam`,showHeader:i.showHeader??!0,emptyTitle:i.emptyTitle??`Ask the assistant`,emptyDescription:i.emptyDescription??`It can answer questions and act through this app's own tools and widgets.`,apiUrl:i.apiUrl??`https://app.astralbeam.ai/api`,authentication:`configured`,colorScheme:i.colorScheme??`system`,theme:i.theme,tools:Object.keys(i.tools??{}),widgets:Object.keys(i.widgets??{}),attachments:i.attachments??!0});let o=n.shadowRoot??n.attachShadow({mode:`open`}),s=document.createElement(`div`);s.className=e,s.style.height=`100%`,o.append(s);let c=matchMedia(`(prefers-color-scheme: dark)`),l=new Set,u=e=>{for(let e of l)s.style.removeProperty(e);l.clear();let t={...i.theme?.light,...e?i.theme?.dark:void 0};for(let[e,n]of Object.entries(t))e.startsWith(`--`)&&(s.style.setProperty(e,n),l.add(e))},d=()=>{let e=i.colorScheme??`system`,t=e===`dark`||e===`system`&&c.matches;s.classList.toggle(`dark`,t),u(t),a?.(`theme`,`color scheme "${e}" resolved to ${t?`dark`:`light`}`,{themeVariables:[...l]})};d(),c.addEventListener(`change`,d);let f=!1,p;return import(`./widget-CfLWAtV7.js`).then(({renderChat:e})=>{a?.(`mount`,`chat chunk loaded`),f||(p=e(o,s,i))}),{update:e=>{i={...i,...e},a=t(i.debug),a?.(`mount`,`options updated`,{changed:Object.keys(e)}),d(),p?.update(i)},reset:()=>p?.reset(),stop:()=>p?.stop(),unmount:()=>{a?.(`mount`,`unmounting chat widget`),f=!0,c.removeEventListener(`change`,d),p?.dispose(),p=void 0,s.remove()}}}export{n as defineTool,r as defineWidget,i as mountAstralBeamChat};
1
+ import{c as e,t}from"./debug-DyjRg3e0.js";function n(e){return e}function r(e){return e}function i(n,r){let i={...r},a=t(i.debug);a?.(`mount`,`mounting chat widget`,{agentId:i.agentId??`(organization default)`,title:i.title??`AstralBeam`,showHeader:i.showHeader??!0,emptyTitle:i.emptyTitle??`Ask the assistant`,emptyDescription:i.emptyDescription??`It can answer questions and act through this app's own tools and widgets.`,apiUrl:i.apiUrl??`https://app.astralbeam.ai/api`,authentication:`configured`,colorScheme:i.colorScheme??`system`,theme:i.theme,tools:Object.keys(i.tools??{}),widgets:Object.keys(i.widgets??{}),attachments:i.attachments??!0});let o=n.shadowRoot??n.attachShadow({mode:`open`}),s=document.createElement(`div`);s.className=e,s.style.height=`100%`,o.append(s);let c=matchMedia(`(prefers-color-scheme: dark)`),l=new Set,u=e=>{for(let e of l)s.style.removeProperty(e);l.clear();let t={...i.theme?.light,...e?i.theme?.dark:void 0};for(let[e,n]of Object.entries(t))e.startsWith(`--`)&&(s.style.setProperty(e,n),l.add(e))},d=()=>{let e=i.colorScheme??`system`,t=e===`dark`||e===`system`&&c.matches;s.classList.toggle(`dark`,t),u(t),a?.(`theme`,`color scheme "${e}" resolved to ${t?`dark`:`light`}`,{themeVariables:[...l]})};d(),c.addEventListener(`change`,d);let f=!1,p;return import(`./widget-PZ-6BF36.js`).then(({renderChat:e})=>{a?.(`mount`,`chat chunk loaded`),f||(p=e(o,s,i))}),{update:e=>{i={...i,...e},a=t(i.debug),a?.(`mount`,`options updated`,{changed:Object.keys(e)}),d(),p?.update(i)},reset:()=>p?.reset(),stop:()=>p?.stop(),unmount:()=>{a?.(`mount`,`unmounting chat widget`),f=!0,c.removeEventListener(`change`,d),p?.dispose(),p=void 0,s.remove()}}}export{n as defineTool,r as defineWidget,i as mountAstralBeamChat};
@@ -8076,6 +8076,19 @@ function describeSandboxCommandRun(run) {
8076
8076
  }
8077
8077
  //#endregion
8078
8078
  //#region src/core/session.ts
8079
+ const CORE_OPTION_KEYS = Object.keys({
8080
+ agentId: true,
8081
+ apiUrl: true,
8082
+ fetchChatAuthToken: true,
8083
+ tools: true,
8084
+ widgets: true,
8085
+ onRenderWidget: true,
8086
+ streamCallbacks: true,
8087
+ debug: true
8088
+ });
8089
+ function sameAgentTools(current, next) {
8090
+ return current.length === next.length && current.every((tool, index) => tool.name === next[index]?.name && tool.title === next[index]?.title);
8091
+ }
8079
8092
  /**
8080
8093
  * The headless AstralBeam chat session: authentication, transport, the tool protocol, and
8081
8094
  * transcript state, with no markup. The drop-in widget is one consumer; a host that owns its
@@ -8091,6 +8104,7 @@ function createAstralBeamChat(options) {
8091
8104
  error: void 0,
8092
8105
  auth: { status: "loading" },
8093
8106
  capabilities: { attachments: true },
8107
+ agentTools: [],
8094
8108
  sandboxStatus: void 0,
8095
8109
  sandbox: {
8096
8110
  files: [],
@@ -8116,7 +8130,9 @@ function createAstralBeamChat(options) {
8116
8130
  debug
8117
8131
  };
8118
8132
  initializeChatAuthentication(authentication).catch(() => void 0);
8133
+ let capabilitiesGeneration = 0;
8119
8134
  const resolveCapabilities = async () => {
8135
+ const generation = ++capabilitiesGeneration;
8120
8136
  try {
8121
8137
  const url = new URL(chatApiUrls(live.apiUrl).config, globalThis.location?.href);
8122
8138
  if (live.agentId) url.searchParams.set("agentId", live.agentId);
@@ -8124,7 +8140,10 @@ function createAstralBeamChat(options) {
8124
8140
  const response = await fetch(url, { headers: { authorization: `Bearer ${token}` } });
8125
8141
  if (!response.ok) throw new Error(`The config request answered ${response.status}`);
8126
8142
  const body = await response.json();
8127
- update({ capabilities: { attachments: body.capabilities?.attachments !== false } });
8143
+ if (generation !== capabilitiesGeneration) return;
8144
+ const attachments = body.capabilities?.attachments !== false;
8145
+ update({ capabilities: { attachments } });
8146
+ debug?.("mount", "agent capabilities resolved", { attachments });
8128
8147
  } catch (error) {
8129
8148
  debug?.("error", "agent capabilities could not be resolved; keeping the defaults", error);
8130
8149
  }
@@ -8143,18 +8162,38 @@ function createAstralBeamChat(options) {
8143
8162
  if (validated == null) throw new Error(`Props for widget "${input.widget}" failed validation`);
8144
8163
  renderCleanups.get(toolCallId)?.();
8145
8164
  renderCleanups.delete(toolCallId);
8165
+ let registered;
8166
+ const release = () => {
8167
+ if (renderCleanups.get(toolCallId) === registered) renderCleanups.delete(toolCallId);
8168
+ };
8146
8169
  const cleanup = live.onRenderWidget?.({
8147
8170
  widget: input.widget,
8148
8171
  props: validated,
8149
- toolCallId
8172
+ toolCallId,
8173
+ release
8150
8174
  });
8151
- if (cleanup) renderCleanups.set(toolCallId, cleanup);
8175
+ if (cleanup) {
8176
+ registered = cleanup;
8177
+ renderCleanups.set(toolCallId, cleanup);
8178
+ }
8152
8179
  return {
8153
8180
  widget: input.widget,
8154
8181
  rendered: live.onRenderWidget !== void 0
8155
8182
  };
8156
8183
  };
8157
- const agentTools = () => buildAgentTools(live.widgets ?? {}, live.tools ?? {}, renderWidget, debug);
8184
+ const buildTools = () => buildAgentTools(live.widgets ?? {}, live.tools ?? {}, renderWidget, debug);
8185
+ const declareTools = () => {
8186
+ const tools = buildTools();
8187
+ const agentTools = tools.map((tool) => {
8188
+ const title = tool.metadata?.["title"];
8189
+ return {
8190
+ name: tool.name,
8191
+ title: typeof title === "string" && title.length > 0 ? title : void 0
8192
+ };
8193
+ });
8194
+ if (!sameAgentTools(state.agentTools, agentTools)) update({ agentTools });
8195
+ return tools;
8196
+ };
8158
8197
  const forwardedProps = () => ({
8159
8198
  ...live.agentId ? { agentId: live.agentId } : {},
8160
8199
  ...live.debug ? { debug: true } : {}
@@ -8168,7 +8207,7 @@ function createAstralBeamChat(options) {
8168
8207
  init
8169
8208
  })
8170
8209
  })),
8171
- tools: agentTools(),
8210
+ tools: declareTools(),
8172
8211
  forwardedProps: forwardedProps(),
8173
8212
  onMessagesChange: (messages) => {
8174
8213
  update({
@@ -8184,30 +8223,40 @@ function createAstralBeamChat(options) {
8184
8223
  onCustomEvent: (eventType, data) => {
8185
8224
  const value = data?.state;
8186
8225
  if (eventType === "astralbeam.sandbox.status" && (value === "starting" || value === "ready" || value === "error")) {
8226
+ debug?.("sandbox", `sandbox ${value}`);
8187
8227
  update({ sandboxStatus: value });
8188
8228
  return;
8189
8229
  }
8190
8230
  debug?.("stream", `custom event "${eventType}"`, data);
8191
- }
8231
+ },
8232
+ onChunk: (chunk) => live.streamCallbacks?.onChunk?.(chunk),
8233
+ onResponse: (response) => live.streamCallbacks?.onResponse?.(response),
8234
+ onFinish: (message) => live.streamCallbacks?.onFinish?.(message),
8235
+ onError: (error) => live.streamCallbacks?.onError?.(error)
8192
8236
  });
8193
8237
  const settleDanglingToolCalls = () => {
8194
8238
  for (const message of state.messages) for (const part of message.parts) {
8195
8239
  if (part.type !== "tool-call" || isSettledToolCall(part)) continue;
8196
- if (part.name === "ask_questionnaire") client.addToolResult({
8197
- toolCallId: part.id,
8198
- tool: part.name,
8199
- output: {
8200
- answers: [],
8201
- skipped: true
8202
- }
8203
- });
8204
- else client.addToolResult({
8205
- toolCallId: part.id,
8206
- tool: part.name,
8207
- output: null,
8208
- state: "output-error",
8209
- errorText: `The application hosting this chat has no implementation for "${part.name}"`
8210
- });
8240
+ if (part.name === "ask_questionnaire") {
8241
+ debug?.("questionnaire", "skipping pending questionnaire before send", { id: part.id });
8242
+ client.addToolResult({
8243
+ toolCallId: part.id,
8244
+ tool: part.name,
8245
+ output: {
8246
+ answers: [],
8247
+ skipped: true
8248
+ }
8249
+ });
8250
+ } else {
8251
+ debug?.("tool", `settling unimplemented tool call "${part.name}" as error`, { id: part.id });
8252
+ client.addToolResult({
8253
+ toolCallId: part.id,
8254
+ tool: part.name,
8255
+ output: null,
8256
+ state: "output-error",
8257
+ errorText: `The application hosting this chat has no implementation for "${part.name}"`
8258
+ });
8259
+ }
8211
8260
  }
8212
8261
  };
8213
8262
  return {
@@ -8227,7 +8276,7 @@ function createAstralBeamChat(options) {
8227
8276
  authentication.fetchChatAuthToken = live.fetchChatAuthToken ?? { url: "/api/astralbeam/token" };
8228
8277
  authentication.debug = debug;
8229
8278
  client.updateOptions({
8230
- tools: agentTools(),
8279
+ tools: declareTools(),
8231
8280
  forwardedProps: forwardedProps()
8232
8281
  });
8233
8282
  if (live.agentId !== agent || live.apiUrl !== apiUrl) resolveCapabilities();
@@ -8238,8 +8287,15 @@ function createAstralBeamChat(options) {
8238
8287
  },
8239
8288
  addToolResult: (result) => client.addToolResult(result),
8240
8289
  stop: () => client.stop(),
8290
+ retryAuthentication: () => {
8291
+ getValidChatAuthToken({
8292
+ ...authentication,
8293
+ force: true
8294
+ }).catch(() => void 0);
8295
+ },
8241
8296
  reload: () => client.reload(),
8242
8297
  reset: () => {
8298
+ debug?.("status", "conversation reset");
8243
8299
  client.clear();
8244
8300
  disposeRenders();
8245
8301
  update({
@@ -8266,9 +8322,5 @@ function createAstralBeamChat(options) {
8266
8322
  function defineTool(tool) {
8267
8323
  return tool;
8268
8324
  }
8269
- /** Declares a host widget; a Standard Schema `parameters` types (and validates) `render`'s props. */
8270
- function defineWidget(widget) {
8271
- return widget;
8272
- }
8273
8325
  //#endregion
8274
- export { DEFAULT_COLOR_SCHEME as C, SANDBOX_WRITE_FILE_TOOL as S, SANDBOX_LIST_FILES_TOOL as _, describeSandboxCommandRun as a, SANDBOX_RUN_COMMAND_TOOL as b, readSandboxCommandRun as c, hasPendingToolRun as d, isSettledToolCall as f, RENDER_WIDGET_TOOL as g, ASK_QUESTIONNAIRE_TOOL as h, collectSandboxActivity as i, readSandboxFileWrite as l, buildAgentTools as m, defineWidget as n, isSandboxTool as o, lastPartInProgress as p, createAstralBeamChat as r, readSandboxArtifact as s, defineTool as t, sandboxRefusal as u, SANDBOX_PUBLISH_ARTIFACT_TOOL as v, SANDBOX_STATUS_EVENT as x, SANDBOX_READ_FILE_TOOL as y };
8326
+ export { DEFAULT_COLOR_SCHEME as C, SANDBOX_WRITE_FILE_TOOL as S, SANDBOX_LIST_FILES_TOOL as _, describeSandboxCommandRun as a, SANDBOX_RUN_COMMAND_TOOL as b, readSandboxCommandRun as c, hasPendingToolRun as d, isSettledToolCall as f, RENDER_WIDGET_TOOL as g, ASK_QUESTIONNAIRE_TOOL as h, collectSandboxActivity as i, readSandboxFileWrite as l, buildAgentTools as m, CORE_OPTION_KEYS as n, isSandboxTool as o, lastPartInProgress as p, createAstralBeamChat as r, readSandboxArtifact as s, defineTool as t, sandboxRefusal as u, SANDBOX_PUBLISH_ARTIFACT_TOOL as v, SANDBOX_STATUS_EVENT as x, SANDBOX_READ_FILE_TOOL as y };
package/dist/core.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- import { A as SandboxActivity, C as AstralBeamChatState, D as WidgetDeclaration, E as ChatAuthenticationState, F as InferParameters, I as JsonSchemaObject, L as ParametersSchema, M as SandboxCommandRun, N as SandboxFileWrite, O as buildAgentTools, P as SandboxStatus, R as StandardSchemaV1, S as AstralBeamChatCoreOptions, T as createAstralBeamChat, _ as sandboxRefusal, a as SANDBOX_LIST_FILES_TOOL, b as lastPartInProgress, c as SANDBOX_RUN_COMMAND_TOOL, d as collectSandboxActivity, f as describeSandboxCommandRun, g as readSandboxFileWrite, h as readSandboxCommandRun, i as RENDER_WIDGET_TOOL, j as SandboxArtifact, k as RenderWidgetInput, l as SANDBOX_STATUS_EVENT, m as readSandboxArtifact, n as defineWidget, o as SANDBOX_PUBLISH_ARTIFACT_TOOL, p as isSandboxTool, r as ASK_QUESTIONNAIRE_TOOL, s as SANDBOX_READ_FILE_TOOL, t as defineTool, u as SANDBOX_WRITE_FILE_TOOL, v as hasPendingToolRun, w as WidgetRenderRequest, x as AstralBeamChatCore, y as isSettledToolCall, z as ToolDefinition } from "./index-TbZxlv54.js";
2
- export { ASK_QUESTIONNAIRE_TOOL, type AstralBeamChatCore, type AstralBeamChatCoreOptions, type AstralBeamChatState, type ChatAuthenticationState, type InferParameters, type JsonSchemaObject, type ParametersSchema, RENDER_WIDGET_TOOL, type RenderWidgetInput, SANDBOX_LIST_FILES_TOOL, SANDBOX_PUBLISH_ARTIFACT_TOOL, SANDBOX_READ_FILE_TOOL, SANDBOX_RUN_COMMAND_TOOL, SANDBOX_STATUS_EVENT, SANDBOX_WRITE_FILE_TOOL, type SandboxActivity, type SandboxArtifact, type SandboxCommandRun, type SandboxFileWrite, type SandboxStatus, type StandardSchemaV1, type ToolDefinition, type WidgetDeclaration, type WidgetRenderRequest, buildAgentTools, collectSandboxActivity, createAstralBeamChat, defineTool, defineWidget, describeSandboxCommandRun, hasPendingToolRun, isSandboxTool, isSettledToolCall, lastPartInProgress, readSandboxArtifact, readSandboxCommandRun, readSandboxFileWrite, sandboxRefusal };
1
+ import { A as RenderWidgetInput, B as ToolDefinition, C as AstralBeamChatState, D as ChatAuthenticationState, E as createAstralBeamChat, F as SandboxStatus, I as InferParameters, L as JsonSchemaObject, M as SandboxArtifact, N as SandboxCommandRun, O as WidgetDeclaration, P as SandboxFileWrite, R as ParametersSchema, S as AstralBeamChatCoreOptions, T as WidgetRenderRequest, _ as hasPendingToolRun, a as SANDBOX_PUBLISH_ARTIFACT_TOOL, b as AgentToolInfo, c as SANDBOX_STATUS_EVENT, d as describeSandboxCommandRun, f as isSandboxTool, g as sandboxRefusal, h as readSandboxFileWrite, i as SANDBOX_LIST_FILES_TOOL, j as SandboxActivity, k as buildAgentTools, l as SANDBOX_WRITE_FILE_TOOL, m as readSandboxCommandRun, n as ASK_QUESTIONNAIRE_TOOL, o as SANDBOX_READ_FILE_TOOL, p as readSandboxArtifact, r as RENDER_WIDGET_TOOL, s as SANDBOX_RUN_COMMAND_TOOL, t as defineTool, u as collectSandboxActivity, v as isSettledToolCall, w as ChatStreamCallbacks, x as AstralBeamChatCore, y as lastPartInProgress, z as StandardSchemaV1 } from "./index-CudekMKM.js";
2
+ export { ASK_QUESTIONNAIRE_TOOL, type AgentToolInfo, type AstralBeamChatCore, type AstralBeamChatCoreOptions, type AstralBeamChatState, type ChatAuthenticationState, type ChatStreamCallbacks, type InferParameters, type JsonSchemaObject, type ParametersSchema, RENDER_WIDGET_TOOL, type RenderWidgetInput, SANDBOX_LIST_FILES_TOOL, SANDBOX_PUBLISH_ARTIFACT_TOOL, SANDBOX_READ_FILE_TOOL, SANDBOX_RUN_COMMAND_TOOL, SANDBOX_STATUS_EVENT, SANDBOX_WRITE_FILE_TOOL, type SandboxActivity, type SandboxArtifact, type SandboxCommandRun, type SandboxFileWrite, type SandboxStatus, type StandardSchemaV1, type ToolDefinition, type WidgetDeclaration, type WidgetRenderRequest, buildAgentTools, collectSandboxActivity, createAstralBeamChat, defineTool, describeSandboxCommandRun, hasPendingToolRun, isSandboxTool, isSettledToolCall, lastPartInProgress, readSandboxArtifact, readSandboxCommandRun, readSandboxFileWrite, sandboxRefusal };
package/dist/core.js CHANGED
@@ -1,2 +1,2 @@
1
- import { S as SANDBOX_WRITE_FILE_TOOL, _ as SANDBOX_LIST_FILES_TOOL, a as describeSandboxCommandRun, b as SANDBOX_RUN_COMMAND_TOOL, c as readSandboxCommandRun, d as hasPendingToolRun, f as isSettledToolCall, g as RENDER_WIDGET_TOOL, h as ASK_QUESTIONNAIRE_TOOL, i as collectSandboxActivity, l as readSandboxFileWrite, m as buildAgentTools, n as defineWidget, o as isSandboxTool, p as lastPartInProgress, r as createAstralBeamChat, s as readSandboxArtifact, t as defineTool, u as sandboxRefusal, v as SANDBOX_PUBLISH_ARTIFACT_TOOL, x as SANDBOX_STATUS_EVENT, y as SANDBOX_READ_FILE_TOOL } from "./core-DYXxodYg.js";
2
- export { ASK_QUESTIONNAIRE_TOOL, RENDER_WIDGET_TOOL, SANDBOX_LIST_FILES_TOOL, SANDBOX_PUBLISH_ARTIFACT_TOOL, SANDBOX_READ_FILE_TOOL, SANDBOX_RUN_COMMAND_TOOL, SANDBOX_STATUS_EVENT, SANDBOX_WRITE_FILE_TOOL, buildAgentTools, collectSandboxActivity, createAstralBeamChat, defineTool, defineWidget, describeSandboxCommandRun, hasPendingToolRun, isSandboxTool, isSettledToolCall, lastPartInProgress, readSandboxArtifact, readSandboxCommandRun, readSandboxFileWrite, sandboxRefusal };
1
+ import { S as SANDBOX_WRITE_FILE_TOOL, _ as SANDBOX_LIST_FILES_TOOL, a as describeSandboxCommandRun, b as SANDBOX_RUN_COMMAND_TOOL, c as readSandboxCommandRun, d as hasPendingToolRun, f as isSettledToolCall, g as RENDER_WIDGET_TOOL, h as ASK_QUESTIONNAIRE_TOOL, i as collectSandboxActivity, l as readSandboxFileWrite, m as buildAgentTools, o as isSandboxTool, p as lastPartInProgress, r as createAstralBeamChat, s as readSandboxArtifact, t as defineTool, u as sandboxRefusal, v as SANDBOX_PUBLISH_ARTIFACT_TOOL, x as SANDBOX_STATUS_EVENT, y as SANDBOX_READ_FILE_TOOL } from "./core-BF1G1dLe.js";
2
+ export { ASK_QUESTIONNAIRE_TOOL, RENDER_WIDGET_TOOL, SANDBOX_LIST_FILES_TOOL, SANDBOX_PUBLISH_ARTIFACT_TOOL, SANDBOX_READ_FILE_TOOL, SANDBOX_RUN_COMMAND_TOOL, SANDBOX_STATUS_EVENT, SANDBOX_WRITE_FILE_TOOL, buildAgentTools, collectSandboxActivity, createAstralBeamChat, defineTool, describeSandboxCommandRun, hasPendingToolRun, isSandboxTool, isSettledToolCall, lastPartInProgress, readSandboxArtifact, readSandboxCommandRun, readSandboxFileWrite, sandboxRefusal };
@@ -3305,6 +3305,47 @@ interface ToolDefinition {
3305
3305
  */
3306
3306
  execute: (input: Record<string, unknown>) => unknown | Promise<unknown>;
3307
3307
  }
3308
+ /**
3309
+ * Limits and accepted types for the composer's file attachments. Every field is optional;
3310
+ * omitting the whole option leaves attachments enabled with the defaults below.
3311
+ */
3312
+ interface AstralBeamChatAttachmentOptions {
3313
+ /** Hides the attach button (and ignores drops and pastes) when `false`. Default `true`. */
3314
+ enabled?: boolean | undefined;
3315
+ /** How many files one message may carry. Default `5`. */
3316
+ maxFiles?: number | undefined;
3317
+ /**
3318
+ * Ceiling for a single file, in bytes. The widget also applies its own per-kind caps
3319
+ * (5 MB image, 10 MB PDF, 1 MB text file), so the smaller of the two wins.
3320
+ */
3321
+ maxFileBytes?: number | undefined;
3322
+ /** Ceiling for all files on one message, in bytes. Default 20 MB. */
3323
+ maxTotalBytes?: number | undefined;
3324
+ /**
3325
+ * Narrows what the composer takes, as MIME types or `type/*` patterns (`["image/*"]` for
3326
+ * images only). Omit to accept everything the chat endpoint supports: PNG, JPEG, WebP and
3327
+ * GIF images, PDFs, and text files (which the endpoint reads as text for the agent).
3328
+ */
3329
+ accept?: readonly string[] | undefined;
3330
+ }
3331
+ /**
3332
+ * Draws host content into `container`, a light-DOM element the widget projects into the
3333
+ * named area. May return a cleanup, called when the slot is replaced and on unmount.
3334
+ */
3335
+ type AstralBeamChatSlotRenderer = (container: HTMLElement) => (() => void) | void;
3336
+ /** Host-rendered replacements for the widget's own chrome; each renders in the host page's style. */
3337
+ interface AstralBeamChatSlots {
3338
+ /** Replaces the header's content (title and reset button); `showHeader: false` still hides the row. */
3339
+ header?: AstralBeamChatSlotRenderer | undefined;
3340
+ /** Replaces the empty-transcript state (icon, headline, and subtitle). */
3341
+ empty?: AstralBeamChatSlotRenderer | undefined;
3342
+ /** Extra controls at the end of the composer's button row, next to send. */
3343
+ composerActions?: AstralBeamChatSlotRenderer | undefined;
3344
+ }
3345
+ /** Color scheme of the chat widget; `"system"` follows the OS `prefers-color-scheme` setting. */
3346
+ type AstralBeamChatColorScheme = "light" | "dark" | "system";
3347
+ /** Overrides for the widget's theming CSS variables, keyed by custom-property name (`"--primary"`). */
3348
+ type AstralBeamChatThemeVariables = Record<`--${string}`, string>;
3308
3349
  /**
3309
3350
  * A token endpoint to call: `{ url, ...init }`, which the widget calls as `fetch(url, init)` with
3310
3351
  * this object's remaining, standard `RequestInit` fields. The init defaults to `POST`,
@@ -3327,6 +3368,79 @@ type AstralBeamChatAuthTokenSource = AstralBeamChatAuthTokenRequest | (() => {
3327
3368
  } | undefined | Promise<{
3328
3369
  token: string;
3329
3370
  } | undefined>);
3371
+ /**
3372
+ * Custom values for the CSS variables the widget's shadcn theme exposes (`--background`,
3373
+ * `--primary`, `--radius`, and the `--font-sans`/`--font-heading`/`--font-mono` stacks, ...),
3374
+ * mirroring shadcn's `:root`/`.dark` split: `light` is the base applied in both color schemes,
3375
+ * and `dark` overrides it when the resolved scheme is dark.
3376
+ */
3377
+ interface AstralBeamChatTheme {
3378
+ light?: AstralBeamChatThemeVariables | undefined;
3379
+ dark?: AstralBeamChatThemeVariables | undefined;
3380
+ }
3381
+ /**
3382
+ * Every option of the drop-in chat widget, and the one documented source the React props and the
3383
+ * headless core options are derived from. Each is optional and accepts an explicit `undefined`, so
3384
+ * a host with `exactOptionalPropertyTypes` can pass a value it does not have yet.
3385
+ */
3386
+ interface MountAstralBeamChatOptions {
3387
+ /**
3388
+ * Public ID of the organization-owned agent. Omit it to use the organization's default agent,
3389
+ * which the dashboard's agents page selects. A change answers the next run with the new agent
3390
+ * and keeps the transcript, which that agent then sees as history.
3391
+ */
3392
+ agentId?: string | undefined;
3393
+ /** Name shown in the widget's header. Default `"AstralBeam"`. */
3394
+ title?: string | undefined;
3395
+ /**
3396
+ * Shows the widget's header, which carries the title and the reset button. `false` hides both
3397
+ * and gives the transcript the full height. Default `true`.
3398
+ */
3399
+ showHeader?: boolean | undefined;
3400
+ /** Headline shown on the empty transcript. Default `"Ask the assistant"`. */
3401
+ emptyTitle?: string | undefined;
3402
+ /** Subtitle shown under the empty transcript's headline. Default describes the app's tools and widgets. */
3403
+ emptyDescription?: string | undefined;
3404
+ /**
3405
+ * Base URL of the AstralBeam API; the widget calls `/chat` and its subroutes under it. Read for
3406
+ * every request, so a change moves the next one. Default `"https://app.astralbeam.ai/api"`, the
3407
+ * hosted cloud; self-hosted deployments must set their own origin.
3408
+ */
3409
+ apiUrl?: string | undefined;
3410
+ /**
3411
+ * Where the short-lived chat auth token comes from: `{ url, ...RequestInit }` for a token
3412
+ * endpoint, or a function that mints `{ token }` in the host page. Read for every token, so a
3413
+ * change applies to the next one, which is minted when the cached token nears expiry. Default
3414
+ * `{ url: "/api/astralbeam/token" }`, posted with the page's cookies.
3415
+ */
3416
+ fetchChatAuthToken?: AstralBeamChatAuthTokenSource | undefined;
3417
+ /** Host-defined tools the agent can call, executed in the host page, keyed by tool name. */
3418
+ tools?: Record<string, ToolDefinition> | undefined;
3419
+ /** Host-defined widgets the agent can render inline in the conversation, keyed by identifier. */
3420
+ widgets?: Record<string, WidgetDefinition> | undefined;
3421
+ /** Host-rendered replacements for parts of the widget's chrome; see `AstralBeamChatSlots`. */
3422
+ slots?: AstralBeamChatSlots | undefined;
3423
+ /**
3424
+ * Shows the collected sandbox panel (every file the agent wrote, with downloads, and the full
3425
+ * command log) above the composer once the sandbox has done work. Off by default: the
3426
+ * transcript already shows each step where it happened. Default `false`.
3427
+ */
3428
+ sandboxPanel?: boolean | undefined;
3429
+ /**
3430
+ * File attachments in the composer, on by default. `false` turns them off; an options object
3431
+ * narrows the limits and accepted types.
3432
+ */
3433
+ attachments?: boolean | AstralBeamChatAttachmentOptions | undefined;
3434
+ /** Color scheme of the widget. Default `"system"`. */
3435
+ colorScheme?: AstralBeamChatColorScheme | undefined;
3436
+ /** Custom values for the widget's theming CSS variables, per color scheme. */
3437
+ theme?: AstralBeamChatTheme | undefined;
3438
+ /**
3439
+ * Logs every SDK action to the browser console with UTC timestamps and full payloads,
3440
+ * and asks the endpoint (via the forwarded props) to log its side of the run too.
3441
+ */
3442
+ debug?: boolean | undefined;
3443
+ }
3330
3444
  //#endregion
3331
3445
  //#region src/lib/debug.d.ts
3332
3446
  declare const CATEGORY_COLORS: {
@@ -3608,26 +3722,38 @@ interface WidgetRenderRequest {
3608
3722
  props: Record<string, unknown>;
3609
3723
  /** Keys the render: a repeat of the same call replaces its own render, not another's. */
3610
3724
  toolCallId: string;
3611
- }
3612
- interface AstralBeamChatCoreOptions {
3613
- /** Public ID of the organization-owned agent; omitted, the organization's default answers. */
3614
- agentId?: string | undefined;
3615
- /** Base URL of the AstralBeam API; `/chat` hangs off it. Default the hosted cloud. */
3616
- apiUrl?: string | undefined;
3617
3725
  /**
3618
- * Where short-lived chat JWTs come from: `{ url, ...RequestInit }` for a token endpoint, or a
3619
- * function minting `{ token }` in the host page. Either runs again on every renewal.
3620
- * Default `{ url: "/api/astralbeam/token" }`.
3726
+ * Drops this session's copy of the render's cleanup, for a host that disposed the render itself;
3727
+ * without it the cleanup and the DOM it captures is held until the next reset.
3621
3728
  */
3622
- fetchChatAuthToken?: AstralBeamChatAuthTokenSource | undefined;
3623
- /** Host tools the agent can call; `execute` runs wherever this session lives. */
3624
- tools?: Record<string, ToolDefinition> | undefined;
3625
- /** Widgets declared to the agent; `onRenderWidget` is asked to draw them. */
3729
+ release: () => void;
3730
+ }
3731
+ /**
3732
+ * Mirrors of the underlying chat client's stream lifecycle, for a consumer that logs or traces the
3733
+ * raw run; the drop-in widget passes its debug console logger here.
3734
+ */
3735
+ interface ChatStreamCallbacks {
3736
+ onChunk?: ((chunk: StreamChunk) => void) | undefined;
3737
+ onResponse?: ((response?: Response) => void) | undefined;
3738
+ onFinish?: ((message: UIMessage) => void) | undefined;
3739
+ onError?: ((error: Error) => void) | undefined;
3740
+ }
3741
+ /**
3742
+ * The transport and tool options of the drop-in widget, minus everything about its UI, plus this
3743
+ * session's own rendering hooks. The shared options are documented on `MountAstralBeamChatOptions`.
3744
+ */
3745
+ interface AstralBeamChatCoreOptions extends Pick<MountAstralBeamChatOptions, "agentId" | "apiUrl" | "fetchChatAuthToken" | "tools" | "debug"> {
3746
+ /** Widgets declared to the agent, without a `render`; `onRenderWidget` is asked to draw them. */
3626
3747
  widgets?: Record<string, WidgetDeclaration> | undefined;
3627
3748
  /** Draws an agent-requested widget however the host wants; may return a cleanup. */
3628
3749
  onRenderWidget?: ((request: WidgetRenderRequest) => (() => void) | void) | undefined;
3629
- /** Logs every action to the console and asks the endpoint to log its side too. */
3630
- debug?: boolean | undefined;
3750
+ /** Stream lifecycle callbacks, read per event so they follow an update. */
3751
+ streamCallbacks?: ChatStreamCallbacks | undefined;
3752
+ }
3753
+ /** One tool as declared to the agent: its name, and the `metadata.title` that labels it. */
3754
+ interface AgentToolInfo {
3755
+ name: string;
3756
+ title: string | undefined;
3631
3757
  }
3632
3758
  interface AstralBeamChatState {
3633
3759
  messages: UIMessage[];
@@ -3639,6 +3765,8 @@ interface AstralBeamChatState {
3639
3765
  capabilities: {
3640
3766
  attachments: boolean;
3641
3767
  };
3768
+ /** The tool set currently declared to the agent, in declaration order. */
3769
+ agentTools: readonly AgentToolInfo[];
3642
3770
  sandboxStatus: SandboxStatus | undefined;
3643
3771
  sandbox: SandboxActivity;
3644
3772
  }
@@ -3657,6 +3785,8 @@ interface AstralBeamChatCore {
3657
3785
  addToolResult: ChatClient["addToolResult"];
3658
3786
  /** Stops the in-flight generation; the transcript keeps what already streamed. */
3659
3787
  stop: () => void;
3788
+ /** Mints a fresh chat auth token, ignoring the cached one; for a retry after a failure. */
3789
+ retryAuthentication: () => void;
3660
3790
  /** Re-runs the last exchange. */
3661
3791
  reload: () => Promise<void>;
3662
3792
  /** Clears the conversation and disposes live widget renders. */
@@ -3724,14 +3854,7 @@ interface TypedToolDefinition<S extends ParametersSchema = JsonSchemaObject> {
3724
3854
  parameters?: S;
3725
3855
  execute: (input: InferParameters<S>) => unknown | Promise<unknown>;
3726
3856
  }
3727
- interface TypedWidgetDefinition<S extends ParametersSchema = JsonSchemaObject> {
3728
- description: string;
3729
- parameters?: S;
3730
- render: (props: InferParameters<S>, container: HTMLElement) => (() => void) | void;
3731
- }
3732
3857
  /** Declares a host tool; a Standard Schema `parameters` types (and validates) `execute`'s input. */
3733
3858
  declare function defineTool<const S extends ParametersSchema = JsonSchemaObject>(tool: TypedToolDefinition<S>): ToolDefinition;
3734
- /** Declares a host widget; a Standard Schema `parameters` types (and validates) `render`'s props. */
3735
- declare function defineWidget<const S extends ParametersSchema = JsonSchemaObject>(widget: TypedWidgetDefinition<S>): WidgetDefinition;
3736
3859
  //#endregion
3737
- export { SandboxActivity as A, AstralBeamChatState as C, WidgetDeclaration as D, ChatAuthenticationState as E, InferParameters as F, JsonSchemaObject as I, ParametersSchema as L, SandboxCommandRun as M, SandboxFileWrite as N, buildAgentTools as O, SandboxStatus as P, StandardSchemaV1 as R, AstralBeamChatCoreOptions as S, createAstralBeamChat as T, sandboxRefusal as _, SANDBOX_LIST_FILES_TOOL as a, lastPartInProgress as b, SANDBOX_RUN_COMMAND_TOOL as c, collectSandboxActivity as d, describeSandboxCommandRun as f, readSandboxFileWrite as g, readSandboxCommandRun as h, RENDER_WIDGET_TOOL as i, SandboxArtifact as j, RenderWidgetInput as k, SANDBOX_STATUS_EVENT as l, readSandboxArtifact as m, defineWidget as n, SANDBOX_PUBLISH_ARTIFACT_TOOL as o, isSandboxTool as p, ASK_QUESTIONNAIRE_TOOL as r, SANDBOX_READ_FILE_TOOL as s, defineTool as t, SANDBOX_WRITE_FILE_TOOL as u, hasPendingToolRun as v, WidgetRenderRequest as w, AstralBeamChatCore as x, isSettledToolCall as y, ToolDefinition as z };
3860
+ export { RenderWidgetInput as A, ToolDefinition as B, AstralBeamChatState as C, ChatAuthenticationState as D, createAstralBeamChat as E, SandboxStatus as F, InferParameters as I, JsonSchemaObject as L, SandboxArtifact as M, SandboxCommandRun as N, WidgetDeclaration as O, SandboxFileWrite as P, ParametersSchema as R, AstralBeamChatCoreOptions as S, WidgetRenderRequest as T, hasPendingToolRun as _, SANDBOX_PUBLISH_ARTIFACT_TOOL as a, AgentToolInfo as b, SANDBOX_STATUS_EVENT as c, describeSandboxCommandRun as d, isSandboxTool as f, sandboxRefusal as g, readSandboxFileWrite as h, SANDBOX_LIST_FILES_TOOL as i, SandboxActivity as j, buildAgentTools as k, SANDBOX_WRITE_FILE_TOOL as l, readSandboxCommandRun as m, ASK_QUESTIONNAIRE_TOOL as n, SANDBOX_READ_FILE_TOOL as o, readSandboxArtifact as p, RENDER_WIDGET_TOOL as r, SANDBOX_RUN_COMMAND_TOOL as s, defineTool as t, collectSandboxActivity as u, isSettledToolCall as v, ChatStreamCallbacks as w, AstralBeamChatCore as x, lastPartInProgress as y, StandardSchemaV1 as z };
package/dist/react.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { C as AstralBeamChatState, S as AstralBeamChatCoreOptions, x as AstralBeamChatCore } from "./index-TbZxlv54.js";
1
+ import { C as AstralBeamChatState, S as AstralBeamChatCoreOptions, x as AstralBeamChatCore } from "./index-CudekMKM.js";
2
2
  import { ReactNode } from "react";
3
- import { AstralBeamChatAttachmentOptions, AstralBeamChatAuthTokenRequest, AstralBeamChatAuthTokenSource, AstralBeamChatColorScheme, AstralBeamChatTheme, InferParameters, JsonSchemaObject, ParametersSchema, ToolDefinition, WidgetDefinition as WidgetDefinition$1, defineTool } from "@astralbeam/sdk/client";
3
+ import { AstralBeamChatAttachmentOptions, AstralBeamChatAuthTokenRequest, AstralBeamChatAuthTokenSource, AstralBeamChatColorScheme, AstralBeamChatTheme, InferParameters, JsonSchemaObject, MountAstralBeamChatOptions, ParametersSchema, ToolDefinition, WidgetDefinition as WidgetDefinition$1, defineTool } from "@astralbeam/sdk/client";
4
4
 
5
5
  //#region src/react/index.d.ts
6
6
  interface WidgetDefinition extends Omit<WidgetDefinition$1, "render"> {
@@ -38,59 +38,20 @@ interface AstralBeamChatRef {
38
38
  /** Stops the in-flight generation, if any; the transcript keeps what already streamed. */
39
39
  stop: () => void;
40
40
  }
41
- interface AstralBeamChatProps {
42
- /**
43
- * Public ID of the organization-owned agent. Omit it to use the organization's default agent,
44
- * which the dashboard's agents page selects. A change answers the next run with the new agent
45
- * and keeps the transcript, which that agent then sees as history.
46
- */
47
- agentId?: string;
48
- /** Name shown in the widget's header. Default `"AstralBeam"`. */
49
- title?: string;
50
- /**
51
- * Shows the widget's header with the title and the reset button; `false` hides both and gives
52
- * the transcript the full height. Default `true`.
53
- */
54
- showHeader?: boolean;
41
+ /**
42
+ * Every mount option as a prop, with the DOM-rendering fields replaced by React ones: a widget
43
+ * renders JSX, and the chrome slots take nodes instead of renderers. The shared options are
44
+ * documented once, on `MountAstralBeamChatOptions`.
45
+ */
46
+ interface AstralBeamChatProps extends Omit<MountAstralBeamChatOptions, "widgets" | "slots"> {
47
+ /** Host-defined widgets the agent can render inline in the conversation, keyed by identifier. */
48
+ widgets?: Record<string, WidgetDefinition> | undefined;
55
49
  /** Replaces the header's content with the host's own React content; `showHeader` still applies. */
56
50
  header?: ReactNode;
57
51
  /** Replaces the empty-transcript state with the host's own React content. */
58
52
  empty?: ReactNode;
59
53
  /** Extra host controls at the end of the composer's button row, next to send. */
60
54
  composerActions?: ReactNode;
61
- /** Headline shown on the empty transcript. Default `"Ask the assistant"`. */
62
- emptyTitle?: string;
63
- /** Subtitle under the empty transcript's headline. */
64
- emptyDescription?: string;
65
- /**
66
- * Base URL of the AstralBeam API; the widget calls `/chat` under it. Read per request, so a
67
- * change moves the next one. Default the hosted cloud.
68
- */
69
- apiUrl?: string;
70
- /**
71
- * Where the short-lived chat JWT comes from: `{ url, ...RequestInit }` for a token endpoint, or
72
- * a function minting `{ token }`, optionally a promise, in the host app. Read per token, and
73
- * the function form runs in the host's React tree, so an inline closure over current auth state
74
- * is fine and needs no memoization. Default `{ url: "/api/astralbeam/token" }`.
75
- */
76
- fetchChatAuthToken?: AstralBeamChatAuthTokenSource;
77
- /** Host-defined tools the agent can call, executed in the host's React app, keyed by name. */
78
- tools?: Record<string, ToolDefinition>;
79
- /** Host-defined widgets the agent can render inline in the conversation, keyed by identifier. */
80
- widgets?: Record<string, WidgetDefinition>;
81
- /** Color scheme of the chat widget. Default `"system"`. */
82
- colorScheme?: AstralBeamChatColorScheme;
83
- /** Custom values for the widget's theming CSS variables, per color scheme. */
84
- theme?: AstralBeamChatTheme | undefined;
85
- /** File attachments in the composer, on by default; `false` turns them off. */
86
- attachments?: boolean | AstralBeamChatAttachmentOptions;
87
- /** Shows the collected sandbox panel (files with downloads, command log) above the composer. Default `false`. */
88
- sandboxPanel?: boolean;
89
- /**
90
- * Logs every SDK action to the browser console with UTC timestamps and full payloads,
91
- * and asks the endpoint to log its side of the run too.
92
- */
93
- debug?: boolean;
94
55
  }
95
56
  declare const AstralBeamChat: import("react").ForwardRefExoticComponent<AstralBeamChatProps & import("react").RefAttributes<AstralBeamChatRef>>;
96
57
  //#endregion
package/dist/react.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as DEFAULT_COLOR_SCHEME, r as createAstralBeamChat } from "./core-DYXxodYg.js";
1
+ import { C as DEFAULT_COLOR_SCHEME, n as CORE_OPTION_KEYS, r as createAstralBeamChat } from "./core-BF1G1dLe.js";
2
2
  import { forwardRef, useEffect, useImperativeHandle, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
3
  import { createPortal } from "react-dom";
4
4
  import { defineTool, mountAstralBeamChat } from "@astralbeam/sdk/client";
@@ -15,19 +15,12 @@ function defineWidget(widget) {
15
15
  * state stay live and nothing needs a remount.
16
16
  */
17
17
  function useAstralBeamChat(options) {
18
- const [core] = useState(() => createAstralBeamChat(options));
18
+ const coreRef = useRef(null);
19
+ coreRef.current ??= createAstralBeamChat(options);
20
+ const core = coreRef.current;
19
21
  useEffect(() => {
20
22
  core.updateOptions(options);
21
- }, [
22
- core,
23
- options.agentId,
24
- options.apiUrl,
25
- options.fetchChatAuthToken,
26
- options.tools,
27
- options.widgets,
28
- options.onRenderWidget,
29
- options.debug
30
- ]);
23
+ }, [core, ...CORE_OPTION_KEYS.map((key) => options[key])]);
31
24
  useEffect(() => () => core.dispose(), [core]);
32
25
  return {
33
26
  ...useSyncExternalStore(core.subscribe, core.getState, core.getState),