@tangle-network/sandbox-ui 0.20.2 → 0.21.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.
@@ -0,0 +1,96 @@
1
+ import '@tangle-network/ui/sdk-hooks';
2
+ import { SessionMessage, SessionPart } from '@tangle-network/ui/types';
3
+
4
+ /** Minimal session info returned by the listing API. */
5
+ interface SessionInfo {
6
+ id: string;
7
+ title: string;
8
+ parentID?: string;
9
+ }
10
+ interface UseSessionStreamOptions {
11
+ /** Base URL of the session proxy (e.g. "http://localhost:9100"). */
12
+ apiUrl: string;
13
+ /** Bearer token for authentication. */
14
+ token: string | null;
15
+ /** Session ID to stream events for. */
16
+ sessionId: string;
17
+ /** Only connect when true. Defaults to true. */
18
+ enabled?: boolean;
19
+ }
20
+ /**
21
+ * Per-message overrides forwarded to the sidecar's send-message endpoint.
22
+ * Every field is optional — omitted fields fall back to the session's
23
+ * backend configuration. Matches `SendMessageRequestSchema` on the sidecar.
24
+ */
25
+ interface SendMessageOptions {
26
+ /** Backend agent identifier override (e.g. a named opencode agent). */
27
+ agent?: string;
28
+ /** Per-turn model override; session backend supplies apiKey/baseUrl. */
29
+ model?: {
30
+ providerID: string;
31
+ modelID: string;
32
+ };
33
+ /** Per-turn system prompt override. */
34
+ system?: string;
35
+ /** Thinking-effort hint; the sidecar maps it to a thinking-token budget. */
36
+ reasoningEffort?: 'low' | 'medium' | 'high';
37
+ }
38
+ interface UseSessionStreamResult {
39
+ /** All messages in the session (fetched + streaming). */
40
+ messages: SessionMessage[];
41
+ /** Part map: messageId → SessionPart[]. */
42
+ partMap: Record<string, SessionPart[]>;
43
+ /** Whether the agent is currently streaming a response. */
44
+ isStreaming: boolean;
45
+ /** Send a text message to the agent, with optional per-turn overrides. */
46
+ send: (text: string, options?: SendMessageOptions) => Promise<void>;
47
+ /** Abort the current agent execution. */
48
+ abort: () => Promise<void>;
49
+ /** Refetch full message history from the API. */
50
+ refetch: () => Promise<void>;
51
+ /** Connection or stream error, if any. */
52
+ error: string | null;
53
+ /** Whether the SSE connection is active. */
54
+ connected: boolean;
55
+ }
56
+ /**
57
+ * Streams chat messages from a sidecar session gateway via SSE.
58
+ *
59
+ * Fetches existing message history on mount, then subscribes to SSE for
60
+ * real-time updates. Maps the sidecar's message format to agent-ui's
61
+ * SessionMessage + partMap format.
62
+ */
63
+ declare function useSessionStream({ apiUrl, token, sessionId, enabled, }: UseSessionStreamOptions): UseSessionStreamResult;
64
+
65
+ interface UseSidecarAuthOptions {
66
+ /** Scoping key for token storage (e.g. botId, sandboxId). */
67
+ resourceId: string;
68
+ /** Base URL of the sidecar or operator API. */
69
+ apiUrl: string;
70
+ /**
71
+ * Sign a plaintext message and return the hex signature.
72
+ * Consuming apps wire this to their wallet library (e.g. wagmi's signMessageAsync).
73
+ */
74
+ signMessage: (message: string) => Promise<string>;
75
+ }
76
+ interface SidecarAuth {
77
+ token: string | null;
78
+ isAuthenticated: boolean;
79
+ isAuthenticating: boolean;
80
+ authenticate: () => Promise<string | null>;
81
+ clearCachedToken: () => void;
82
+ error: string | null;
83
+ }
84
+ /**
85
+ * Generic sidecar PASETO challenge/response auth.
86
+ *
87
+ * Flow:
88
+ * 1. POST /api/auth/challenge → { nonce, message, expires_at }
89
+ * 2. signMessage(message) → signature (provided by consuming app)
90
+ * 3. POST /api/auth/session → { token, address, expires_at }
91
+ *
92
+ * Tokens are cached in localStorage and auto-refreshed 5 minutes before expiry.
93
+ */
94
+ declare function useSidecarAuth({ resourceId, apiUrl, signMessage }: UseSidecarAuthOptions): SidecarAuth;
95
+
96
+ export { type SessionInfo as S, type UseSessionStreamOptions as U, type SidecarAuth as a, type UseSessionStreamResult as b, type UseSidecarAuthOptions as c, useSidecarAuth as d, type SendMessageOptions as e, useSessionStream as u };
@@ -1,78 +1,3 @@
1
1
  export { AgentStreamEvent, AppendUserMessageOptions, ApplySdkEventOptions, AutomationStreamEvent, BeginAssistantMessageOptions, BotStreamEvent, CompleteAssistantMessageOptions, ConnectionState, RealtimeSessionOptions, RealtimeSessionRegistry, RealtimeSessionRegistryProps, RealtimeSessionState, RealtimeSessionTarget, SSEEvent, SdkSessionAttachment, SdkSessionEvent, SdkSessionSeed, TaskStreamEvent, TerminalStreamEvent, UseRunGroupsOptions, UseSSEStreamOptions, UseSSEStreamResult, UseSdkSessionOptions, UseSdkSessionReturn, UseToolCallStreamReturn, useAutoScroll, useDropdownMenu, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useToolCallStream } from '@tangle-network/ui/sdk-hooks';
2
- import { SessionMessage, SessionPart } from '@tangle-network/ui/types';
3
-
4
- /** Minimal session info returned by the listing API. */
5
- interface SessionInfo {
6
- id: string;
7
- title: string;
8
- parentID?: string;
9
- }
10
- interface UseSessionStreamOptions {
11
- /** Base URL of the session proxy (e.g. "http://localhost:9100"). */
12
- apiUrl: string;
13
- /** Bearer token for authentication. */
14
- token: string | null;
15
- /** Session ID to stream events for. */
16
- sessionId: string;
17
- /** Only connect when true. Defaults to true. */
18
- enabled?: boolean;
19
- }
20
- interface UseSessionStreamResult {
21
- /** All messages in the session (fetched + streaming). */
22
- messages: SessionMessage[];
23
- /** Part map: messageId → SessionPart[]. */
24
- partMap: Record<string, SessionPart[]>;
25
- /** Whether the agent is currently streaming a response. */
26
- isStreaming: boolean;
27
- /** Send a text message to the agent. */
28
- send: (text: string) => Promise<void>;
29
- /** Abort the current agent execution. */
30
- abort: () => Promise<void>;
31
- /** Refetch full message history from the API. */
32
- refetch: () => Promise<void>;
33
- /** Connection or stream error, if any. */
34
- error: string | null;
35
- /** Whether the SSE connection is active. */
36
- connected: boolean;
37
- }
38
- /**
39
- * Streams chat messages from a sidecar session gateway via SSE.
40
- *
41
- * Fetches existing message history on mount, then subscribes to SSE for
42
- * real-time updates. Maps the sidecar's message format to agent-ui's
43
- * SessionMessage + partMap format.
44
- */
45
- declare function useSessionStream({ apiUrl, token, sessionId, enabled, }: UseSessionStreamOptions): UseSessionStreamResult;
46
-
47
- interface UseSidecarAuthOptions {
48
- /** Scoping key for token storage (e.g. botId, sandboxId). */
49
- resourceId: string;
50
- /** Base URL of the sidecar or operator API. */
51
- apiUrl: string;
52
- /**
53
- * Sign a plaintext message and return the hex signature.
54
- * Consuming apps wire this to their wallet library (e.g. wagmi's signMessageAsync).
55
- */
56
- signMessage: (message: string) => Promise<string>;
57
- }
58
- interface SidecarAuth {
59
- token: string | null;
60
- isAuthenticated: boolean;
61
- isAuthenticating: boolean;
62
- authenticate: () => Promise<string | null>;
63
- clearCachedToken: () => void;
64
- error: string | null;
65
- }
66
- /**
67
- * Generic sidecar PASETO challenge/response auth.
68
- *
69
- * Flow:
70
- * 1. POST /api/auth/challenge → { nonce, message, expires_at }
71
- * 2. signMessage(message) → signature (provided by consuming app)
72
- * 3. POST /api/auth/session → { token, address, expires_at }
73
- *
74
- * Tokens are cached in localStorage and auto-refreshed 5 minutes before expiry.
75
- */
76
- declare function useSidecarAuth({ resourceId, apiUrl, signMessage }: UseSidecarAuthOptions): SidecarAuth;
77
-
78
- export { type SessionInfo, type SidecarAuth, type UseSessionStreamOptions, type UseSessionStreamResult, type UseSidecarAuthOptions, useSessionStream, useSidecarAuth };
2
+ export { S as SessionInfo, a as SidecarAuth, U as UseSessionStreamOptions, b as UseSessionStreamResult, c as UseSidecarAuthOptions, u as useSessionStream, d as useSidecarAuth } from './sdk-hooks-jUbIngSV.js';
3
+ import '@tangle-network/ui/types';
package/dist/sdk-hooks.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  useSessionStream,
3
3
  useSidecarAuth
4
- } from "./chunk-CMY7W45U.js";
4
+ } from "./chunk-MEDE37J5.js";
5
5
 
6
6
  // src/sdk-hooks.ts
7
7
  import {
package/dist/styles.css CHANGED
@@ -668,9 +668,6 @@
668
668
  .h-28 {
669
669
  height: calc(var(--spacing) * 28);
670
670
  }
671
- .h-32 {
672
- height: calc(var(--spacing) * 32);
673
- }
674
671
  .h-48 {
675
672
  height: calc(var(--spacing) * 48);
676
673
  }
@@ -2758,9 +2755,6 @@
2758
2755
  .underline {
2759
2756
  text-decoration-line: underline;
2760
2757
  }
2761
- .underline-offset-2 {
2762
- text-underline-offset: 2px;
2763
- }
2764
2758
  .underline-offset-4 {
2765
2759
  text-underline-offset: 4px;
2766
2760
  }
@@ -3503,11 +3497,6 @@
3503
3497
  color: var(--color-red-400);
3504
3498
  }
3505
3499
  }
3506
- .focus\:underline {
3507
- &:focus {
3508
- text-decoration-line: underline;
3509
- }
3510
- }
3511
3500
  .focus\:ring-0 {
3512
3501
  &:focus {
3513
3502
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
@@ -0,0 +1,88 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as React from 'react';
3
+
4
+ interface BillingSubscription {
5
+ status: string;
6
+ tierName: string;
7
+ renewsAt: string;
8
+ }
9
+ interface BillingBalance {
10
+ available: number;
11
+ used: number;
12
+ }
13
+ interface BillingUsage {
14
+ period: string;
15
+ total: number;
16
+ byModel: Record<string, number>;
17
+ }
18
+ interface BillingDashboardProps {
19
+ subscription: BillingSubscription | null;
20
+ balance: BillingBalance;
21
+ usage: BillingUsage;
22
+ onManageSubscription: () => void;
23
+ onAddCredits: () => void;
24
+ variant?: "sandbox";
25
+ className?: string;
26
+ cardClassName?: string;
27
+ }
28
+ declare function BillingDashboard({ subscription, balance, usage, onManageSubscription, onAddCredits, variant, className, cardClassName, }: BillingDashboardProps): react_jsx_runtime.JSX.Element;
29
+
30
+ interface PricingTier {
31
+ id: string;
32
+ name: string;
33
+ description: string;
34
+ monthlyPriceCents: number;
35
+ yearlyPriceCents?: number;
36
+ features: string[];
37
+ recommended?: boolean;
38
+ creditsPerMonth?: number;
39
+ monthlyPriceId?: string;
40
+ yearlyPriceId?: string;
41
+ }
42
+ interface PricingPageProps {
43
+ tiers: PricingTier[];
44
+ currentTierId?: string;
45
+ billingPeriod: "monthly" | "yearly";
46
+ onBillingPeriodChange: (period: "monthly" | "yearly") => void;
47
+ onSelectTier: (tierId: string) => void;
48
+ variant?: "sandbox";
49
+ loading?: boolean;
50
+ className?: string;
51
+ cardClassName?: string;
52
+ }
53
+ /**
54
+ * Formats an integer cent amount as a human-readable USD price.
55
+ * Whole-dollar amounts omit decimals ($10), fractional amounts show two ($10.99).
56
+ * Returns "$0" for non-finite or negative inputs.
57
+ * @param cents - Amount in whole US cents (e.g. 1099 for $10.99).
58
+ */
59
+ declare function formatPrice(cents: number): string;
60
+ declare function PricingPage({ tiers, currentTierId, billingPeriod, onBillingPeriodChange, onSelectTier, loading, className, }: PricingPageProps): react_jsx_runtime.JSX.Element;
61
+
62
+ interface UsageDataPoint {
63
+ date: string;
64
+ value: number;
65
+ }
66
+ interface UsageChartProps {
67
+ data: UsageDataPoint[];
68
+ title: string;
69
+ unit: string;
70
+ className?: string;
71
+ }
72
+ declare function UsageChart({ data, title, unit, className }: UsageChartProps): react_jsx_runtime.JSX.Element;
73
+
74
+ interface TemplateCardData {
75
+ id: string;
76
+ name: string;
77
+ description: string;
78
+ icon?: React.ReactNode;
79
+ tags?: string[];
80
+ }
81
+ interface TemplateCardProps {
82
+ template: TemplateCardData;
83
+ onUseTemplate: (templateId: string) => void;
84
+ className?: string;
85
+ }
86
+ declare function TemplateCard({ template, onUseTemplate, className }: TemplateCardProps): react_jsx_runtime.JSX.Element;
87
+
88
+ export { type BillingBalance as B, PricingPage as P, TemplateCard as T, UsageChart as U, BillingDashboard as a, type BillingDashboardProps as b, type BillingSubscription as c, type BillingUsage as d, type PricingPageProps as e, type PricingTier as f, type TemplateCardData as g, type TemplateCardProps as h, type UsageChartProps as i, type UsageDataPoint as j, formatPrice as k };
@@ -275,6 +275,13 @@ interface SandboxWorkbenchSessionProps extends Omit<ChatContainerProps, "classNa
275
275
  subtitle?: ReactNode;
276
276
  meta?: ReactNode;
277
277
  headerActions?: ReactNode;
278
+ /**
279
+ * Controls rendered as a strip attached beneath the chat composer —
280
+ * harness/model/effort pickers, token meters, etc. Use
281
+ * `AgentSessionControls` from `@tangle-network/sandbox-ui/chat` for the
282
+ * standard set.
283
+ */
284
+ composerControls?: ReactNode;
278
285
  renderRunActions?: ChatContainerProps["renderRunActions"];
279
286
  renderUserMessageActions?: ChatContainerProps["renderUserMessageActions"];
280
287
  renderToolActions?: ChatContainerProps["renderToolActions"];
package/dist/workspace.js CHANGED
@@ -14,7 +14,7 @@ import {
14
14
  TaskBoard,
15
15
  TerminalPanel,
16
16
  WorkspaceLayout
17
- } from "./chunk-CP2L6B53.js";
17
+ } from "./chunk-R6NONXFC.js";
18
18
  import "./chunk-EI44GEQ5.js";
19
19
  export {
20
20
  AgentWorkbench,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.20.2",
3
+ "version": "0.21.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",
@@ -176,23 +176,23 @@
176
176
  "@xterm/xterm": "^6.0.0",
177
177
  "jsdom": "^29.0.2",
178
178
  "marked": "^17.0.5",
179
+ "postcss": "^8.5.8",
180
+ "postcss-import": "^16.1.1",
181
+ "react": "^19.1.0",
182
+ "react-dom": "^19.1.0",
179
183
  "react-markdown": "^10.1.0",
180
184
  "react-pdf": "^9.2.1",
181
185
  "react-syntax-highlighter": "^16.1.1",
182
186
  "rehype-sanitize": "^6.0.0",
183
187
  "remark-gfm": "^4.0.1",
184
- "turndown": "^7.2.2",
185
- "yjs": "^13.6.30",
186
- "postcss": "^8.5.8",
187
- "postcss-import": "^16.1.1",
188
- "react": "^19.1.0",
189
- "react-dom": "^19.1.0",
190
188
  "storybook": "^8.6.18",
191
189
  "tailwindcss": "^4.1.4",
192
190
  "tailwindcss-animate": "^1.0.7",
193
191
  "tsup": "^8.4.0",
192
+ "turndown": "^7.2.2",
194
193
  "typescript": "^5.8.3",
195
194
  "vite": "^8.0.5",
196
- "vitest": "^4.1.3"
195
+ "vitest": "^4.1.3",
196
+ "yjs": "^13.6.30"
197
197
  }
198
198
  }