@tangle-network/sandbox-ui 0.40.0 → 0.41.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.
@@ -1,5 +1,5 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import { ReactNode } from 'react';
2
+ import * as react_jsx_runtime from 'react/jsx-runtime';
3
3
 
4
4
  /**
5
5
  * Wire + UI types for the in-app assistant panel. The wire shapes mirror the
@@ -7,6 +7,7 @@ import { ReactNode } from 'react';
7
7
  * `routes/assistant.ts`). Drift here only mis-renders the client; the server
8
8
  * is the source of truth for what it accepts and emits.
9
9
  */
10
+
10
11
  /** Request body for `POST /api/v1/assistant/chat`. */
11
12
  interface ChatRequest {
12
13
  message: string;
@@ -132,14 +133,30 @@ type AssistantStreamEvent = {
132
133
  type ChatRole = "user" | "assistant" | "status" | "tool";
133
134
  /** Live status of a tool-activity chip. */
134
135
  type ToolActivityStatus = "running" | "ok" | "failed";
136
+ /** The outcome of a finished read-only tool, retained on the chip so a renderer
137
+ * can show the result body (not just the name + status). Mirrors the
138
+ * `tool_result` event: a success carries the tool's `result`; a failure carries
139
+ * the error. Absent while the tool is still running. */
140
+ type ToolOutcome = {
141
+ ok: true;
142
+ result?: unknown;
143
+ } | {
144
+ ok: false;
145
+ error?: {
146
+ code: string;
147
+ message: string;
148
+ };
149
+ };
135
150
  interface ChatMessage {
136
151
  id: string;
137
152
  role: ChatRole;
138
153
  text: string;
139
- /** Present only on `tool` messages — the activity's tool name and state. */
154
+ /** Present only on `tool` messages — the activity's tool name, state, and (once
155
+ * finished) its outcome. */
140
156
  tool?: {
141
157
  name: string;
142
158
  status: ToolActivityStatus;
159
+ outcome?: ToolOutcome;
143
160
  };
144
161
  }
145
162
  /** A mutating action the assistant proposed, awaiting the user's confirmation. */
@@ -161,6 +178,34 @@ interface UsageInfo {
161
178
  balanceUsd: number | null;
162
179
  replayed: boolean;
163
180
  }
181
+ /**
182
+ * The transcript slice handed to a host-supplied `renderTranscript` (see
183
+ * {@link AssistantPanelProps}). It lets a host swap ONLY the conversation
184
+ * rendering — to use its own message renderer — while the panel keeps owning the
185
+ * dock chrome, composer, model picker, history, transport, and proposal
186
+ * orchestration. The bound `renderProposal` returns the panel's own proposal
187
+ * card so the host can place it (e.g. inline after the proposing turn) without
188
+ * re-implementing the confirm/cancel flow.
189
+ */
190
+ interface AssistantTranscriptView {
191
+ messages: ChatMessage[];
192
+ /** The current turn's reasoning/thinking text, if any (streamed before the
193
+ * answer for reasoning models). */
194
+ reasoning: string | null;
195
+ /** Id of the assistant message currently accumulating deltas, if any. */
196
+ streamingId: string | null;
197
+ /** Model slug the current/most-recent turn ran against, or null. */
198
+ model: string | null;
199
+ /** True while a turn is streaming. */
200
+ isStreaming: boolean;
201
+ /** True while the agent is working but has produced no visible output yet
202
+ * (drives a "thinking" affordance). */
203
+ isThinking: boolean;
204
+ pendingProposals: PendingProposal[];
205
+ /** The panel's bound proposal card for a pending proposal — render it where the
206
+ * confirm/cancel UI should appear. */
207
+ renderProposal: (proposal: PendingProposal) => ReactNode;
208
+ }
164
209
 
165
210
  /**
166
211
  * Configurable network client for the assistant panel: the chat SSE stream, the
@@ -419,8 +464,12 @@ interface AssistantDockProps {
419
464
  renderGraph?: (yaml: string) => ReactNode;
420
465
  /** Called after a workflow-mutating tool is confirmed (host re-fetches its list). */
421
466
  onWorkflowMutation?: () => void;
467
+ /** Swap the conversation rendering for a host-supplied renderer (see
468
+ * {@link AssistantPanelProps.renderTranscript}); the dock chrome, composer,
469
+ * transport, and proposal flow stay owned by the panel. */
470
+ renderTranscript?: (view: AssistantTranscriptView) => ReactNode;
422
471
  }
423
- declare function AssistantDock({ userId, navigate, balanceUsd, formatMoney, renderGraph, onWorkflowMutation, }: AssistantDockProps): react_jsx_runtime.JSX.Element;
472
+ declare function AssistantDock({ userId, navigate, balanceUsd, formatMoney, renderGraph, onWorkflowMutation, renderTranscript, }: AssistantDockProps): react_jsx_runtime.JSX.Element;
424
473
 
425
474
  interface AssistantPanelProps {
426
475
  chat: AssistantChat;
@@ -435,8 +484,14 @@ interface AssistantPanelProps {
435
484
  /** Render workflow YAML as a node graph in a proposal card (the `./workflows`
436
485
  * WorkflowGraph). When absent, proposals show YAML as text. */
437
486
  renderGraph?: (yaml: string) => ReactNode;
487
+ /** Swap ONLY the conversation rendering for a host-supplied renderer (e.g. a
488
+ * different chat-message component), while the panel keeps owning the header,
489
+ * composer, model picker, history, transport, and proposal orchestration.
490
+ * Receives the transcript slice plus a bound proposal card to place. When
491
+ * absent, the built-in `AgentTimeline` renders the conversation. */
492
+ renderTranscript?: (view: AssistantTranscriptView) => ReactNode;
438
493
  }
439
- declare function AssistantPanel({ chat, userId, onClose, navigate, balanceUsd, formatMoney, renderGraph, }: AssistantPanelProps): react_jsx_runtime.JSX.Element;
494
+ declare function AssistantPanel({ chat, userId, onClose, navigate, balanceUsd, formatMoney, renderGraph, renderTranscript, }: AssistantPanelProps): react_jsx_runtime.JSX.Element;
440
495
 
441
496
  interface ProposalCardProps {
442
497
  proposal: PendingProposal;
@@ -468,4 +523,4 @@ declare function AssistantLauncherProvider({ children, }: {
468
523
  }): react_jsx_runtime.JSX.Element;
469
524
  declare function useAssistantLauncher(): AssistantLauncher;
470
525
 
471
- export { type AssistantChat, type AssistantClient, type AssistantClientConfig, AssistantClientProvider, AssistantDock, type AssistantDockProps, type AssistantLauncher, AssistantLauncherProvider, type AssistantModelOption, type AssistantModels, type AssistantModelsResult, AssistantPanel, type AssistantPanelProps, type AssistantStreamEvent, type AssistantThreadSummary, type AssistantThreads, type ChatMessage, type ChatRequest, type ChatRole, type ConfirmResult, type ConnectionRequirement, type ConnectionRequirementKind, type DeltaEventData, type DoneEventData, type ErrorEventData, type PendingProposal, ProposalCard, type ProposalCardProps, type ReasoningEventData, type ThreadEventData, type ThreadHistoryResult, type ToolActivityStatus, type ToolCallEventData, type ToolProposalEventData, type ToolResultEventData, type UsageEventData, type UsageInfo, type UseAssistantChatOptions, createAssistantClient, useAssistantChat, useAssistantClient, useAssistantLauncher, useAssistantModels, useAssistantThreads };
526
+ export { type AssistantChat, type AssistantClient, type AssistantClientConfig, AssistantClientProvider, AssistantDock, type AssistantDockProps, type AssistantLauncher, AssistantLauncherProvider, type AssistantModelOption, type AssistantModels, type AssistantModelsResult, AssistantPanel, type AssistantPanelProps, type AssistantStreamEvent, type AssistantThreadSummary, type AssistantThreads, type AssistantTranscriptView, type ChatMessage, type ChatRequest, type ChatRole, type ConfirmResult, type ConnectionRequirement, type ConnectionRequirementKind, type DeltaEventData, type DoneEventData, type ErrorEventData, type PendingProposal, ProposalCard, type ProposalCardProps, type ReasoningEventData, type ThreadEventData, type ThreadHistoryResult, type ToolActivityStatus, type ToolCallEventData, type ToolOutcome, type ToolProposalEventData, type ToolResultEventData, type UsageEventData, type UsageInfo, type UseAssistantChatOptions, createAssistantClient, useAssistantChat, useAssistantClient, useAssistantLauncher, useAssistantModels, useAssistantThreads };
package/dist/assistant.js CHANGED
@@ -857,11 +857,16 @@ function applyStreamEvent(state, event) {
857
857
  const chipId = `tool-${event.data.callId}`;
858
858
  const status = event.data.ok ? "ok" : "failed";
859
859
  const errText = event.data.ok ? "" : event.data.error?.message ?? "unknown error";
860
+ const outcome = event.data.ok ? { ok: true, result: event.data.output } : { ok: false, error: event.data.error };
860
861
  if (state.messages.some((m) => m.id === chipId)) {
861
862
  return {
862
863
  ...state,
863
864
  messages: state.messages.map(
864
- (m) => m.id === chipId ? { ...m, text: errText, tool: { name: event.data.name, status } } : m
865
+ (m) => m.id === chipId ? {
866
+ ...m,
867
+ text: errText,
868
+ tool: { name: event.data.name, status, outcome }
869
+ } : m
865
870
  )
866
871
  };
867
872
  }
@@ -869,7 +874,7 @@ function applyStreamEvent(state, event) {
869
874
  id: chipId,
870
875
  role: "tool",
871
876
  text: errText,
872
- tool: { name: event.data.name, status }
877
+ tool: { name: event.data.name, status, outcome }
873
878
  };
874
879
  return { ...state, messages: capMessages([...state.messages, chip]) };
875
880
  }
@@ -1828,7 +1833,8 @@ function AssistantPanel({
1828
1833
  navigate,
1829
1834
  balanceUsd = null,
1830
1835
  formatMoney = defaultFormatMoney,
1831
- renderGraph
1836
+ renderGraph,
1837
+ renderTranscript
1832
1838
  }) {
1833
1839
  const models = useAssistantModels();
1834
1840
  const threads = useAssistantThreads(userId);
@@ -1850,7 +1856,7 @@ function AssistantPanel({
1850
1856
  renderGraph
1851
1857
  }
1852
1858
  );
1853
- const items = buildAssistantTimeline(state, renderProposal);
1859
+ const isThinking = assistantIsThinking(state);
1854
1860
  const openHistory = () => {
1855
1861
  setHistoryOpen((v) => {
1856
1862
  const next = !v;
@@ -1972,11 +1978,20 @@ function AssistantPanel({
1972
1978
  "aria-live": "polite",
1973
1979
  className: "min-h-0 flex-1 overflow-y-auto px-2 py-3",
1974
1980
  style: { fontSize: `${font.scale}rem` },
1975
- children: /* @__PURE__ */ jsx4(
1981
+ children: renderTranscript ? renderTranscript({
1982
+ messages: state.messages,
1983
+ reasoning: state.reasoning,
1984
+ streamingId: state.streamingId,
1985
+ model: state.model,
1986
+ isStreaming: streaming,
1987
+ isThinking,
1988
+ pendingProposals: state.pendingProposals,
1989
+ renderProposal
1990
+ }) : /* @__PURE__ */ jsx4(
1976
1991
  AgentTimeline,
1977
1992
  {
1978
- items,
1979
- isThinking: assistantIsThinking(state),
1993
+ items: buildAssistantTimeline(state, renderProposal),
1994
+ isThinking,
1980
1995
  emptyState: /* @__PURE__ */ jsx4("p", { className: "px-4 py-8 text-center text-muted-foreground text-sm", children: EMPTY_STATE })
1981
1996
  }
1982
1997
  )
@@ -2168,7 +2183,8 @@ function AssistantDock({
2168
2183
  balanceUsd = null,
2169
2184
  formatMoney,
2170
2185
  renderGraph,
2171
- onWorkflowMutation
2186
+ onWorkflowMutation,
2187
+ renderTranscript
2172
2188
  }) {
2173
2189
  const { open, openAssistant, closeAssistant } = useAssistantLauncher();
2174
2190
  const chat = useAssistantChat(userId, { onWorkflowMutation });
@@ -2272,7 +2288,8 @@ function AssistantDock({
2272
2288
  navigate,
2273
2289
  balanceUsd,
2274
2290
  formatMoney,
2275
- renderGraph
2291
+ renderGraph,
2292
+ renderTranscript
2276
2293
  },
2277
2294
  userId ?? "anon"
2278
2295
  ),
@@ -10,7 +10,7 @@ import * as react_jsx_runtime from 'react/jsx-runtime';
10
10
  interface IntegrationConnection {
11
11
  id: string;
12
12
  providerId: string;
13
- connectorId: string;
13
+ connectorId?: string;
14
14
  status: "connected" | "pending" | "revoked" | "expired" | (string & {});
15
15
  grantedScopes?: string[];
16
16
  account?: {
@@ -215,7 +215,7 @@ function buildConnectionIndex(connections) {
215
215
  const index = /* @__PURE__ */ new Map();
216
216
  for (const conn of connections) {
217
217
  if (conn.status === "revoked") continue;
218
- index.set(`${conn.providerId}:${conn.connectorId}`, conn);
218
+ index.set(`${conn.providerId}:${conn.connectorId ?? conn.providerId}`, conn);
219
219
  }
220
220
  return index;
221
221
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.40.0",
3
+ "version": "0.41.0",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",