@stigmer/react 0.3.4 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/billing/AutoRechargeCard.d.ts +38 -0
- package/billing/AutoRechargeCard.d.ts.map +1 -0
- package/billing/AutoRechargeCard.js +90 -0
- package/billing/AutoRechargeCard.js.map +1 -0
- package/billing/BillingSection.d.ts +32 -0
- package/billing/BillingSection.d.ts.map +1 -0
- package/billing/BillingSection.js +81 -0
- package/billing/BillingSection.js.map +1 -0
- package/billing/CreditBalanceCard.d.ts +25 -0
- package/billing/CreditBalanceCard.d.ts.map +1 -0
- package/billing/CreditBalanceCard.js +28 -0
- package/billing/CreditBalanceCard.js.map +1 -0
- package/billing/CreditLedgerTable.d.ts +22 -0
- package/billing/CreditLedgerTable.d.ts.map +1 -0
- package/billing/CreditLedgerTable.js +75 -0
- package/billing/CreditLedgerTable.js.map +1 -0
- package/billing/CreditPackGrid.d.ts +31 -0
- package/billing/CreditPackGrid.d.ts.map +1 -0
- package/billing/CreditPackGrid.js +35 -0
- package/billing/CreditPackGrid.js.map +1 -0
- package/billing/LowBalanceBanner.d.ts +26 -0
- package/billing/LowBalanceBanner.d.ts.map +1 -0
- package/billing/LowBalanceBanner.js +33 -0
- package/billing/LowBalanceBanner.js.map +1 -0
- package/billing/PaymentMethodCard.d.ts +35 -0
- package/billing/PaymentMethodCard.d.ts.map +1 -0
- package/billing/PaymentMethodCard.js +48 -0
- package/billing/PaymentMethodCard.js.map +1 -0
- package/billing/credit-packs.d.ts +25 -0
- package/billing/credit-packs.d.ts.map +1 -0
- package/billing/credit-packs.js +39 -0
- package/billing/credit-packs.js.map +1 -0
- package/billing/format.d.ts +39 -0
- package/billing/format.d.ts.map +1 -0
- package/billing/format.js +90 -0
- package/billing/format.js.map +1 -0
- package/billing/index.d.ts +32 -0
- package/billing/index.d.ts.map +1 -0
- package/billing/index.js +21 -0
- package/billing/index.js.map +1 -0
- package/billing/useBillingAccount.d.ts +40 -0
- package/billing/useBillingAccount.d.ts.map +1 -0
- package/billing/useBillingAccount.js +35 -0
- package/billing/useBillingAccount.js.map +1 -0
- package/billing/useBillingUsageReport.d.ts +42 -0
- package/billing/useBillingUsageReport.d.ts.map +1 -0
- package/billing/useBillingUsageReport.js +43 -0
- package/billing/useBillingUsageReport.js.map +1 -0
- package/billing/useCreateBillingPortalSession.d.ts +35 -0
- package/billing/useCreateBillingPortalSession.d.ts.map +1 -0
- package/billing/useCreateBillingPortalSession.js +50 -0
- package/billing/useCreateBillingPortalSession.js.map +1 -0
- package/billing/useCreateCheckoutSession.d.ts +54 -0
- package/billing/useCreateCheckoutSession.d.ts.map +1 -0
- package/billing/useCreateCheckoutSession.js +58 -0
- package/billing/useCreateCheckoutSession.js.map +1 -0
- package/billing/useCreditLedger.d.ts +48 -0
- package/billing/useCreditLedger.d.ts.map +1 -0
- package/billing/useCreditLedger.js +39 -0
- package/billing/useCreditLedger.js.map +1 -0
- package/billing/useCustomerModelPricing.d.ts +41 -0
- package/billing/useCustomerModelPricing.d.ts.map +1 -0
- package/billing/useCustomerModelPricing.js +37 -0
- package/billing/useCustomerModelPricing.js.map +1 -0
- package/billing/useSetAutoRechargeConfig.d.ts +50 -0
- package/billing/useSetAutoRechargeConfig.d.ts.map +1 -0
- package/billing/useSetAutoRechargeConfig.js +53 -0
- package/billing/useSetAutoRechargeConfig.js.map +1 -0
- package/composer/ComposerToolbar.js +1 -1
- package/composer/ComposerToolbar.js.map +1 -1
- package/composer/SessionComposer.d.ts +1 -1
- package/composer/SessionComposer.d.ts.map +1 -1
- package/composer/SessionComposer.js +19 -4
- package/composer/SessionComposer.js.map +1 -1
- package/composer/__tests__/SessionComposer-memo.test.d.ts +2 -0
- package/composer/__tests__/SessionComposer-memo.test.d.ts.map +1 -0
- package/composer/__tests__/SessionComposer-memo.test.js +23 -0
- package/composer/__tests__/SessionComposer-memo.test.js.map +1 -0
- package/execution/ApprovalCard.d.ts +5 -1
- package/execution/ApprovalCard.d.ts.map +1 -1
- package/execution/ApprovalCard.js +7 -3
- package/execution/ApprovalCard.js.map +1 -1
- package/execution/ExecutionPhaseBadge.d.ts +1 -1
- package/execution/ExecutionPhaseBadge.d.ts.map +1 -1
- package/execution/ExecutionPhaseBadge.js +3 -2
- package/execution/ExecutionPhaseBadge.js.map +1 -1
- package/execution/MessageEntry.d.ts +7 -3
- package/execution/MessageEntry.d.ts.map +1 -1
- package/execution/MessageEntry.js +19 -8
- package/execution/MessageEntry.js.map +1 -1
- package/execution/MessageThread.d.ts +84 -3
- package/execution/MessageThread.d.ts.map +1 -1
- package/execution/MessageThread.js +113 -65
- package/execution/MessageThread.js.map +1 -1
- package/execution/SetupProgress.d.ts +1 -1
- package/execution/SetupProgress.d.ts.map +1 -1
- package/execution/SetupProgress.js +3 -3
- package/execution/SetupProgress.js.map +1 -1
- package/execution/SubAgentSection.d.ts +5 -1
- package/execution/SubAgentSection.d.ts.map +1 -1
- package/execution/SubAgentSection.js +13 -7
- package/execution/SubAgentSection.js.map +1 -1
- package/execution/ThreadSkeleton.d.ts +22 -0
- package/execution/ThreadSkeleton.d.ts.map +1 -0
- package/execution/ThreadSkeleton.js +26 -0
- package/execution/ThreadSkeleton.js.map +1 -0
- package/execution/ToolCallGroup.d.ts +16 -1
- package/execution/ToolCallGroup.d.ts.map +1 -1
- package/execution/ToolCallGroup.js +31 -3
- package/execution/ToolCallGroup.js.map +1 -1
- package/execution/UsageWidget.d.ts +1 -1
- package/execution/__tests__/message-entry.test.d.ts +2 -0
- package/execution/__tests__/message-entry.test.d.ts.map +1 -0
- package/execution/__tests__/message-entry.test.js +178 -0
- package/execution/__tests__/message-entry.test.js.map +1 -0
- package/execution/__tests__/thread-keys.test.d.ts +2 -0
- package/execution/__tests__/thread-keys.test.d.ts.map +1 -0
- package/execution/__tests__/thread-keys.test.js +289 -0
- package/execution/__tests__/thread-keys.test.js.map +1 -0
- package/execution/__tests__/thread-memoization.test.d.ts +2 -0
- package/execution/__tests__/thread-memoization.test.d.ts.map +1 -0
- package/execution/__tests__/thread-memoization.test.js +262 -0
- package/execution/__tests__/thread-memoization.test.js.map +1 -0
- package/execution/__tests__/thread-skeleton.test.d.ts +2 -0
- package/execution/__tests__/thread-skeleton.test.d.ts.map +1 -0
- package/execution/__tests__/thread-skeleton.test.js +35 -0
- package/execution/__tests__/thread-skeleton.test.js.map +1 -0
- package/execution/__tests__/useExecutionStream.test.js +73 -10
- package/execution/__tests__/useExecutionStream.test.js.map +1 -1
- package/execution/__tests__/useSessionVariables-stability.test.d.ts +2 -0
- package/execution/__tests__/useSessionVariables-stability.test.d.ts.map +1 -0
- package/execution/__tests__/useSessionVariables-stability.test.js +69 -0
- package/execution/__tests__/useSessionVariables-stability.test.js.map +1 -0
- package/execution/__tests__/virtualized-thread.test.d.ts +2 -0
- package/execution/__tests__/virtualized-thread.test.d.ts.map +1 -0
- package/execution/__tests__/virtualized-thread.test.js +274 -0
- package/execution/__tests__/virtualized-thread.test.js.map +1 -0
- package/execution/index.d.ts +2 -0
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +1 -0
- package/execution/index.js.map +1 -1
- package/execution/useExecutionStream.d.ts +35 -10
- package/execution/useExecutionStream.d.ts.map +1 -1
- package/execution/useExecutionStream.js +79 -40
- package/execution/useExecutionStream.js.map +1 -1
- package/execution/useSessionVariables.d.ts.map +1 -1
- package/execution/useSessionVariables.js +4 -3
- package/execution/useSessionVariables.js.map +1 -1
- package/github/useGitHubConnection.d.ts.map +1 -1
- package/github/useGitHubConnection.js +5 -4
- package/github/useGitHubConnection.js.map +1 -1
- package/identity-account/index.d.ts +2 -0
- package/identity-account/index.d.ts.map +1 -0
- package/identity-account/index.js +2 -0
- package/identity-account/index.js.map +1 -0
- package/identity-account/useIdentityAccountGate.d.ts +81 -0
- package/identity-account/useIdentityAccountGate.d.ts.map +1 -0
- package/identity-account/useIdentityAccountGate.js +100 -0
- package/identity-account/useIdentityAccountGate.js.map +1 -0
- package/index.d.ts +10 -4
- package/index.d.ts.map +1 -1
- package/index.js +8 -2
- package/index.js.map +1 -1
- package/internal/FetchCacheProvider.d.ts +44 -0
- package/internal/FetchCacheProvider.d.ts.map +1 -0
- package/internal/FetchCacheProvider.js +61 -0
- package/internal/FetchCacheProvider.js.map +1 -0
- package/internal/JumpToLatestButton.d.ts +14 -0
- package/internal/JumpToLatestButton.d.ts.map +1 -0
- package/internal/JumpToLatestButton.js +19 -0
- package/internal/JumpToLatestButton.js.map +1 -0
- package/internal/ThreadItemWrapper.d.ts +20 -0
- package/internal/ThreadItemWrapper.d.ts.map +1 -0
- package/internal/ThreadItemWrapper.js +44 -0
- package/internal/ThreadItemWrapper.js.map +1 -0
- package/internal/VirtualizedThread.d.ts +25 -0
- package/internal/VirtualizedThread.d.ts.map +1 -0
- package/internal/VirtualizedThread.js +58 -0
- package/internal/VirtualizedThread.js.map +1 -0
- package/internal/__tests__/fetch-cache.test.d.ts +2 -0
- package/internal/__tests__/fetch-cache.test.d.ts.map +1 -0
- package/internal/__tests__/fetch-cache.test.js +182 -0
- package/internal/__tests__/fetch-cache.test.js.map +1 -0
- package/internal/__tests__/stream-controller.test.d.ts +2 -0
- package/internal/__tests__/stream-controller.test.d.ts.map +1 -0
- package/internal/__tests__/stream-controller.test.js +294 -0
- package/internal/__tests__/stream-controller.test.js.map +1 -0
- package/internal/__tests__/thread-animation.test.d.ts +2 -0
- package/internal/__tests__/thread-animation.test.d.ts.map +1 -0
- package/internal/__tests__/thread-animation.test.js +79 -0
- package/internal/__tests__/thread-animation.test.js.map +1 -0
- package/internal/__tests__/useAutoScroll.test.d.ts +2 -0
- package/internal/__tests__/useAutoScroll.test.d.ts.map +1 -0
- package/internal/__tests__/useAutoScroll.test.js +188 -0
- package/internal/__tests__/useAutoScroll.test.js.map +1 -0
- package/internal/__tests__/useFetch-cache.test.d.ts +2 -0
- package/internal/__tests__/useFetch-cache.test.d.ts.map +1 -0
- package/internal/__tests__/useFetch-cache.test.js +137 -0
- package/internal/__tests__/useFetch-cache.test.js.map +1 -0
- package/internal/dev/__tests__/use-key-stability.test.d.ts +2 -0
- package/internal/dev/__tests__/use-key-stability.test.d.ts.map +1 -0
- package/internal/dev/__tests__/use-key-stability.test.js +72 -0
- package/internal/dev/__tests__/use-key-stability.test.js.map +1 -0
- package/internal/dev/__tests__/use-render-tracer.test.d.ts +2 -0
- package/internal/dev/__tests__/use-render-tracer.test.d.ts.map +1 -0
- package/internal/dev/__tests__/use-render-tracer.test.js +55 -0
- package/internal/dev/__tests__/use-render-tracer.test.js.map +1 -0
- package/internal/dev/dom-counter.d.ts +14 -0
- package/internal/dev/dom-counter.d.ts.map +1 -0
- package/internal/dev/dom-counter.js +39 -0
- package/internal/dev/dom-counter.js.map +1 -0
- package/internal/dev/index.d.ts +6 -0
- package/internal/dev/index.d.ts.map +1 -0
- package/internal/dev/index.js +6 -0
- package/internal/dev/index.js.map +1 -0
- package/internal/dev/profiler-wrapper.d.ts +16 -0
- package/internal/dev/profiler-wrapper.d.ts.map +1 -0
- package/internal/dev/profiler-wrapper.js +31 -0
- package/internal/dev/profiler-wrapper.js.map +1 -0
- package/internal/dev/use-key-stability.d.ts +22 -0
- package/internal/dev/use-key-stability.d.ts.map +1 -0
- package/internal/dev/use-key-stability.js +67 -0
- package/internal/dev/use-key-stability.js.map +1 -0
- package/internal/dev/use-render-tracer.d.ts +13 -0
- package/internal/dev/use-render-tracer.d.ts.map +1 -0
- package/internal/dev/use-render-tracer.js +57 -0
- package/internal/dev/use-render-tracer.js.map +1 -0
- package/internal/dev/use-stream-rate.d.ts +23 -0
- package/internal/dev/use-stream-rate.d.ts.map +1 -0
- package/internal/dev/use-stream-rate.js +94 -0
- package/internal/dev/use-stream-rate.js.map +1 -0
- package/internal/fetch-cache.d.ts +72 -0
- package/internal/fetch-cache.d.ts.map +1 -0
- package/internal/fetch-cache.js +118 -0
- package/internal/fetch-cache.js.map +1 -0
- package/internal/store/__tests__/conversation-store.test.d.ts +2 -0
- package/internal/store/__tests__/conversation-store.test.d.ts.map +1 -0
- package/internal/store/__tests__/conversation-store.test.js +200 -0
- package/internal/store/__tests__/conversation-store.test.js.map +1 -0
- package/internal/store/__tests__/structural-share.test.d.ts +2 -0
- package/internal/store/__tests__/structural-share.test.d.ts.map +1 -0
- package/internal/store/__tests__/structural-share.test.js +368 -0
- package/internal/store/__tests__/structural-share.test.js.map +1 -0
- package/internal/store/conversation-store.d.ts +62 -0
- package/internal/store/conversation-store.d.ts.map +1 -0
- package/internal/store/conversation-store.js +95 -0
- package/internal/store/conversation-store.js.map +1 -0
- package/internal/store/index.d.ts +31 -0
- package/internal/store/index.d.ts.map +1 -0
- package/internal/store/index.js +54 -0
- package/internal/store/index.js.map +1 -0
- package/internal/store/structural-share.d.ts +13 -0
- package/internal/store/structural-share.d.ts.map +1 -0
- package/internal/store/structural-share.js +240 -0
- package/internal/store/structural-share.js.map +1 -0
- package/internal/stream-controller.d.ts +85 -0
- package/internal/stream-controller.d.ts.map +1 -0
- package/internal/stream-controller.js +146 -0
- package/internal/stream-controller.js.map +1 -0
- package/internal/useAutoScroll.d.ts +32 -0
- package/internal/useAutoScroll.d.ts.map +1 -0
- package/internal/useAutoScroll.js +97 -0
- package/internal/useAutoScroll.js.map +1 -0
- package/internal/useFetch.d.ts +14 -0
- package/internal/useFetch.d.ts.map +1 -1
- package/internal/useFetch.js +32 -2
- package/internal/useFetch.js.map +1 -1
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +3 -3
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.d.ts.map +1 -1
- package/mcp-server/useMcpServerOAuthConnect.js +37 -9
- package/mcp-server/useMcpServerOAuthConnect.js.map +1 -1
- package/package.json +7 -5
- package/session/__tests__/useNewSessionFlow.test.js +16 -0
- package/session/__tests__/useNewSessionFlow.test.js.map +1 -1
- package/session/__tests__/usePersistedModel.test.d.ts +2 -0
- package/session/__tests__/usePersistedModel.test.d.ts.map +1 -0
- package/session/__tests__/usePersistedModel.test.js +82 -0
- package/session/__tests__/usePersistedModel.test.js.map +1 -0
- package/session/__tests__/useSession.test.d.ts +2 -0
- package/session/__tests__/useSession.test.d.ts.map +1 -0
- package/session/__tests__/useSession.test.js +130 -0
- package/session/__tests__/useSession.test.js.map +1 -0
- package/session/useNewSessionFlow.d.ts.map +1 -1
- package/session/useNewSessionFlow.js +12 -6
- package/session/useNewSessionFlow.js.map +1 -1
- package/session/usePersistedModel.d.ts +3 -0
- package/session/usePersistedModel.d.ts.map +1 -1
- package/session/usePersistedModel.js +27 -2
- package/session/usePersistedModel.js.map +1 -1
- package/session/useSession.d.ts.map +1 -1
- package/session/useSession.js +1 -1
- package/session/useSession.js.map +1 -1
- package/session/useSessionConversation.d.ts.map +1 -1
- package/session/useSessionConversation.js +9 -1
- package/session/useSessionConversation.js.map +1 -1
- package/session/useSessionExecutions.d.ts.map +1 -1
- package/session/useSessionExecutions.js +1 -1
- package/session/useSessionExecutions.js.map +1 -1
- package/session/useSessionPageFlow.js +1 -1
- package/session/useSessionPageFlow.js.map +1 -1
- package/session/useSessionUsage.d.ts +24 -40
- package/session/useSessionUsage.d.ts.map +1 -1
- package/session/useSessionUsage.js +64 -97
- package/session/useSessionUsage.js.map +1 -1
- package/settings/BillingSection.d.ts +3 -0
- package/settings/BillingSection.d.ts.map +1 -0
- package/settings/BillingSection.js +3 -0
- package/settings/BillingSection.js.map +1 -0
- package/settings/index.d.ts +2 -0
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +1 -0
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.js +1 -1
- package/settings/settings-nav.js.map +1 -1
- package/src/billing/AutoRechargeCard.tsx +274 -0
- package/src/billing/BillingSection.tsx +255 -0
- package/src/billing/CreditBalanceCard.tsx +81 -0
- package/src/billing/CreditLedgerTable.tsx +281 -0
- package/src/billing/CreditPackGrid.tsx +132 -0
- package/src/billing/LowBalanceBanner.tsx +67 -0
- package/src/billing/PaymentMethodCard.tsx +133 -0
- package/src/billing/credit-packs.ts +54 -0
- package/src/billing/format.ts +97 -0
- package/src/billing/index.ts +51 -0
- package/src/billing/useBillingAccount.ts +64 -0
- package/src/billing/useBillingUsageReport.ts +73 -0
- package/src/billing/useCreateBillingPortalSession.ts +76 -0
- package/src/billing/useCreateCheckoutSession.ts +101 -0
- package/src/billing/useCreditLedger.ts +79 -0
- package/src/billing/useCustomerModelPricing.ts +67 -0
- package/src/billing/useSetAutoRechargeConfig.ts +90 -0
- package/src/composer/ComposerToolbar.tsx +1 -1
- package/src/composer/SessionComposer.tsx +22 -4
- package/src/composer/__tests__/SessionComposer-memo.test.ts +26 -0
- package/src/execution/ApprovalCard.tsx +7 -3
- package/src/execution/ExecutionPhaseBadge.tsx +3 -2
- package/src/execution/MessageEntry.tsx +27 -16
- package/src/execution/MessageThread.tsx +308 -131
- package/src/execution/SetupProgress.tsx +3 -3
- package/src/execution/SubAgentSection.tsx +14 -6
- package/src/execution/ThreadSkeleton.tsx +73 -0
- package/src/execution/ToolCallGroup.tsx +36 -3
- package/src/execution/UsageWidget.tsx +1 -1
- package/src/execution/__tests__/message-entry.test.tsx +236 -0
- package/src/execution/__tests__/thread-keys.test.ts +409 -0
- package/src/execution/__tests__/thread-memoization.test.ts +320 -0
- package/src/execution/__tests__/thread-skeleton.test.tsx +44 -0
- package/src/execution/__tests__/useExecutionStream.test.tsx +109 -12
- package/src/execution/__tests__/useSessionVariables-stability.test.ts +95 -0
- package/src/execution/__tests__/virtualized-thread.test.tsx +401 -0
- package/src/execution/index.ts +3 -0
- package/src/execution/useExecutionStream.ts +123 -48
- package/src/execution/useSessionVariables.ts +17 -12
- package/src/github/useGitHubConnection.ts +18 -13
- package/src/identity-account/index.ts +5 -0
- package/src/identity-account/useIdentityAccountGate.ts +163 -0
- package/src/index.ts +73 -0
- package/src/internal/FetchCacheProvider.tsx +74 -0
- package/src/internal/JumpToLatestButton.tsx +61 -0
- package/src/internal/ThreadItemWrapper.tsx +65 -0
- package/src/internal/VirtualizedThread.tsx +162 -0
- package/src/internal/__tests__/fetch-cache.test.ts +230 -0
- package/src/internal/__tests__/stream-controller.test.ts +395 -0
- package/src/internal/__tests__/thread-animation.test.tsx +121 -0
- package/src/internal/__tests__/useAutoScroll.test.tsx +261 -0
- package/src/internal/__tests__/useFetch-cache.test.ts +214 -0
- package/src/internal/dev/__tests__/use-key-stability.test.ts +124 -0
- package/src/internal/dev/__tests__/use-render-tracer.test.ts +78 -0
- package/src/internal/dev/dom-counter.ts +47 -0
- package/src/internal/dev/index.ts +5 -0
- package/src/internal/dev/profiler-wrapper.tsx +52 -0
- package/src/internal/dev/use-key-stability.ts +86 -0
- package/src/internal/dev/use-render-tracer.ts +70 -0
- package/src/internal/dev/use-stream-rate.ts +138 -0
- package/src/internal/fetch-cache.ts +155 -0
- package/src/internal/store/__tests__/conversation-store.test.ts +257 -0
- package/src/internal/store/__tests__/structural-share.test.ts +454 -0
- package/src/internal/store/conversation-store.ts +128 -0
- package/src/internal/store/index.ts +68 -0
- package/src/internal/store/structural-share.ts +318 -0
- package/src/internal/stream-controller.ts +201 -0
- package/src/internal/useAutoScroll.ts +121 -0
- package/src/internal/useFetch.ts +51 -2
- package/src/mcp-server/McpServerDetailView.tsx +15 -0
- package/src/mcp-server/useMcpServerOAuthConnect.ts +37 -9
- package/src/session/__tests__/useNewSessionFlow.test.tsx +22 -0
- package/src/session/__tests__/usePersistedModel.test.tsx +117 -0
- package/src/session/__tests__/useSession.test.tsx +187 -0
- package/src/session/useNewSessionFlow.ts +12 -6
- package/src/session/usePersistedModel.ts +28 -2
- package/src/session/useSession.ts +1 -0
- package/src/session/useSessionConversation.ts +11 -2
- package/src/session/useSessionExecutions.ts +1 -0
- package/src/session/useSessionPageFlow.ts +1 -1
- package/src/session/useSessionUsage.ts +102 -123
- package/src/settings/BillingSection.tsx +4 -0
- package/src/settings/index.ts +2 -0
- package/src/settings/settings-nav.ts +1 -1
- package/src/styles.css +31 -0
- package/src/usage/AgentBreakdownList.tsx +147 -0
- package/src/usage/CreditRunwayIndicator.tsx +71 -0
- package/src/usage/ExportButton.tsx +115 -0
- package/src/usage/HarnessSplitCard.tsx +103 -0
- package/src/usage/OrgUsagePanel.tsx +109 -45
- package/src/usage/index.ts +15 -0
- package/src/usage/useExportCSV.ts +115 -0
- package/src/usage/useOrgUsageReport.ts +2 -1
- package/src/workspace/__tests__/useWorkspaceEntries-stability.test.ts +76 -0
- package/src/workspace/useWorkspaceEntries.ts +16 -11
- package/styles.css +1 -1
- package/usage/AgentBreakdownList.d.ts +21 -0
- package/usage/AgentBreakdownList.d.ts.map +1 -0
- package/usage/AgentBreakdownList.js +44 -0
- package/usage/AgentBreakdownList.js.map +1 -0
- package/usage/CreditRunwayIndicator.d.ts +21 -0
- package/usage/CreditRunwayIndicator.d.ts.map +1 -0
- package/usage/CreditRunwayIndicator.js +38 -0
- package/usage/CreditRunwayIndicator.js.map +1 -0
- package/usage/ExportButton.d.ts +20 -0
- package/usage/ExportButton.d.ts.map +1 -0
- package/usage/ExportButton.js +36 -0
- package/usage/ExportButton.js.map +1 -0
- package/usage/HarnessSplitCard.d.ts +17 -0
- package/usage/HarnessSplitCard.d.ts.map +1 -0
- package/usage/HarnessSplitCard.js +38 -0
- package/usage/HarnessSplitCard.js.map +1 -0
- package/usage/OrgUsagePanel.d.ts.map +1 -1
- package/usage/OrgUsagePanel.js +30 -22
- package/usage/OrgUsagePanel.js.map +1 -1
- package/usage/index.d.ts +10 -0
- package/usage/index.d.ts.map +1 -1
- package/usage/index.js +5 -0
- package/usage/index.js.map +1 -1
- package/usage/useExportCSV.d.ts +23 -0
- package/usage/useExportCSV.d.ts.map +1 -0
- package/usage/useExportCSV.js +81 -0
- package/usage/useExportCSV.js.map +1 -0
- package/usage/useOrgUsageReport.d.ts +2 -1
- package/usage/useOrgUsageReport.d.ts.map +1 -1
- package/usage/useOrgUsageReport.js +2 -1
- package/usage/useOrgUsageReport.js.map +1 -1
- package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts +2 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.d.ts.map +1 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.js +57 -0
- package/workspace/__tests__/useWorkspaceEntries-stability.test.js.map +1 -0
- package/workspace/useWorkspaceEntries.d.ts.map +1 -1
- package/workspace/useWorkspaceEntries.js +5 -4
- package/workspace/useWorkspaceEntries.js.map +1 -1
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { useStigmer } from "../hooks";
|
|
5
|
+
import { toError } from "../internal/toError";
|
|
6
|
+
|
|
7
|
+
/** Return value of {@link useCreateBillingPortalSession}. */
|
|
8
|
+
export interface UseCreateBillingPortalSessionReturn {
|
|
9
|
+
/**
|
|
10
|
+
* Open the Stripe Customer Portal for payment method management.
|
|
11
|
+
*
|
|
12
|
+
* On success, redirects the user to the Stripe-hosted portal page.
|
|
13
|
+
* The promise resolves before the redirect occurs.
|
|
14
|
+
*/
|
|
15
|
+
readonly openPortal: (orgId: string) => Promise<void>;
|
|
16
|
+
/** `true` while the portal session is being created. */
|
|
17
|
+
readonly isLoading: boolean;
|
|
18
|
+
/** Error from the last failed attempt, or `null` when healthy. */
|
|
19
|
+
readonly error: Error | null;
|
|
20
|
+
/** Reset `error` to `null`. */
|
|
21
|
+
readonly clearError: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Behavior hook that opens the Stripe Customer Portal for payment
|
|
26
|
+
* method management.
|
|
27
|
+
*
|
|
28
|
+
* Wraps `billing.createBillingPortalSession` with loading and error
|
|
29
|
+
* state management. On success, redirects the user to the Stripe-hosted
|
|
30
|
+
* portal. Payment method changes are synced back via webhooks.
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* ```tsx
|
|
34
|
+
* const { openPortal, isLoading } = useCreateBillingPortalSession();
|
|
35
|
+
*
|
|
36
|
+
* <button onClick={() => openPortal(orgId)} disabled={isLoading}>
|
|
37
|
+
* Manage payment methods
|
|
38
|
+
* </button>
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export function useCreateBillingPortalSession(): UseCreateBillingPortalSessionReturn {
|
|
42
|
+
const stigmer = useStigmer();
|
|
43
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
44
|
+
const [error, setError] = useState<Error | null>(null);
|
|
45
|
+
|
|
46
|
+
const clearError = useCallback(() => setError(null), []);
|
|
47
|
+
|
|
48
|
+
const openPortal = useCallback(
|
|
49
|
+
async (orgId: string): Promise<void> => {
|
|
50
|
+
setIsLoading(true);
|
|
51
|
+
setError(null);
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
const returnUrl =
|
|
55
|
+
typeof window !== "undefined" ? window.location.href : "";
|
|
56
|
+
|
|
57
|
+
const response = await stigmer.billing.createBillingPortalSession({
|
|
58
|
+
orgId,
|
|
59
|
+
returnUrl,
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (response.portalUrl) {
|
|
63
|
+
window.location.href = response.portalUrl;
|
|
64
|
+
}
|
|
65
|
+
} catch (err) {
|
|
66
|
+
setError(toError(err));
|
|
67
|
+
throw err;
|
|
68
|
+
} finally {
|
|
69
|
+
setIsLoading(false);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
[stigmer],
|
|
73
|
+
);
|
|
74
|
+
|
|
75
|
+
return { openPortal, isLoading, error, clearError };
|
|
76
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import type { CreateCreditCheckoutSessionResponse } from "@stigmer/protos/ai/stigmer/billing/v1/io_pb";
|
|
5
|
+
import { useStigmer } from "../hooks";
|
|
6
|
+
import { toError } from "../internal/toError";
|
|
7
|
+
|
|
8
|
+
/** Parameters for {@link useCreateCheckoutSession}'s `createSession` callback. */
|
|
9
|
+
export interface CreateCheckoutSessionInput {
|
|
10
|
+
/** Organization purchasing credits. */
|
|
11
|
+
readonly orgId: string;
|
|
12
|
+
/** Credit pack to purchase (e.g., "starter", "growth", "team"). */
|
|
13
|
+
readonly packId: string;
|
|
14
|
+
/** URL to redirect to after successful payment. */
|
|
15
|
+
readonly successUrl: string;
|
|
16
|
+
/** URL to redirect to if the user cancels checkout. */
|
|
17
|
+
readonly cancelUrl: string;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Return value of {@link useCreateCheckoutSession}. */
|
|
21
|
+
export interface UseCreateCheckoutSessionReturn {
|
|
22
|
+
/**
|
|
23
|
+
* Create a Stripe Checkout Session and redirect the user.
|
|
24
|
+
*
|
|
25
|
+
* On success, sets `window.location.href` to the Stripe-hosted
|
|
26
|
+
* checkout page URL. The promise resolves with the response before
|
|
27
|
+
* the redirect occurs, allowing callers to perform cleanup if needed.
|
|
28
|
+
*/
|
|
29
|
+
readonly createSession: (
|
|
30
|
+
input: CreateCheckoutSessionInput,
|
|
31
|
+
) => Promise<CreateCreditCheckoutSessionResponse>;
|
|
32
|
+
/** `true` while the checkout session is being created. */
|
|
33
|
+
readonly isSubmitting: boolean;
|
|
34
|
+
/** Error from the last failed attempt, or `null` when healthy. */
|
|
35
|
+
readonly error: Error | null;
|
|
36
|
+
/** Reset `error` to `null`. */
|
|
37
|
+
readonly clearError: () => void;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Behavior hook that creates a Stripe Checkout Session for credit
|
|
42
|
+
* pack purchases.
|
|
43
|
+
*
|
|
44
|
+
* Wraps `billing.createCreditCheckoutSession` with loading and error
|
|
45
|
+
* state management. On success, redirects the user to the Stripe-hosted
|
|
46
|
+
* checkout page. Credits are provisioned asynchronously via webhook
|
|
47
|
+
* after payment succeeds.
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const { createSession, isSubmitting, error } = useCreateCheckoutSession();
|
|
52
|
+
*
|
|
53
|
+
* const handleBuy = () => {
|
|
54
|
+
* createSession({
|
|
55
|
+
* orgId,
|
|
56
|
+
* packId: "growth",
|
|
57
|
+
* successUrl: `${window.location.origin}/settings/billing?checkout=success`,
|
|
58
|
+
* cancelUrl: `${window.location.origin}/settings/billing`,
|
|
59
|
+
* });
|
|
60
|
+
* };
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export function useCreateCheckoutSession(): UseCreateCheckoutSessionReturn {
|
|
64
|
+
const stigmer = useStigmer();
|
|
65
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
66
|
+
const [error, setError] = useState<Error | null>(null);
|
|
67
|
+
|
|
68
|
+
const clearError = useCallback(() => setError(null), []);
|
|
69
|
+
|
|
70
|
+
const createSession = useCallback(
|
|
71
|
+
async (
|
|
72
|
+
input: CreateCheckoutSessionInput,
|
|
73
|
+
): Promise<CreateCreditCheckoutSessionResponse> => {
|
|
74
|
+
setIsSubmitting(true);
|
|
75
|
+
setError(null);
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
const response = await stigmer.billing.createCreditCheckoutSession({
|
|
79
|
+
orgId: input.orgId,
|
|
80
|
+
packId: input.packId,
|
|
81
|
+
successUrl: input.successUrl,
|
|
82
|
+
cancelUrl: input.cancelUrl,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if (response.checkoutUrl) {
|
|
86
|
+
window.location.href = response.checkoutUrl;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return response;
|
|
90
|
+
} catch (err) {
|
|
91
|
+
setError(toError(err));
|
|
92
|
+
throw err;
|
|
93
|
+
} finally {
|
|
94
|
+
setIsSubmitting(false);
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
[stigmer],
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
return { createSession, isSubmitting, error, clearError };
|
|
101
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
CreditLedgerResponse,
|
|
5
|
+
} from "@stigmer/protos/ai/stigmer/billing/v1/io_pb";
|
|
6
|
+
import type { LedgerEntryType } from "@stigmer/protos/ai/stigmer/billing/v1/enum_pb";
|
|
7
|
+
import { useStigmer } from "../hooks";
|
|
8
|
+
import { useFetch } from "../internal/useFetch";
|
|
9
|
+
|
|
10
|
+
/** Return value of {@link useCreditLedger}. */
|
|
11
|
+
export interface UseCreditLedgerReturn {
|
|
12
|
+
/** The ledger response, or `null` before the first successful fetch. */
|
|
13
|
+
readonly ledger: CreditLedgerResponse | null;
|
|
14
|
+
/** `true` while the initial fetch is in flight. */
|
|
15
|
+
readonly isLoading: boolean;
|
|
16
|
+
/** `true` while a background refetch is in flight and stale data is shown. */
|
|
17
|
+
readonly isRefetching: boolean;
|
|
18
|
+
/** Error from the last failed request, or `null` when healthy. */
|
|
19
|
+
readonly error: Error | null;
|
|
20
|
+
/** Discard cached data and re-fetch from the server. */
|
|
21
|
+
readonly refetch: () => void;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Options for {@link useCreditLedger}. */
|
|
25
|
+
export interface UseCreditLedgerOptions {
|
|
26
|
+
/** 1-based page number. Defaults to 1. */
|
|
27
|
+
readonly pageNum?: number;
|
|
28
|
+
/** Page size. Defaults to 20. */
|
|
29
|
+
readonly pageSize?: number;
|
|
30
|
+
/** Filter to specific ledger entry types. Empty means all types. */
|
|
31
|
+
readonly typeFilter?: LedgerEntryType[];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Data hook that fetches paginated credit ledger entries for an organization.
|
|
36
|
+
*
|
|
37
|
+
* Calls `billing.getCreditLedger` with optional pagination and type
|
|
38
|
+
* filtering. Returns the entries and total page count for building
|
|
39
|
+
* pagination controls.
|
|
40
|
+
*
|
|
41
|
+
* Pass `null` as `orgId` to skip fetching (stable no-op).
|
|
42
|
+
*
|
|
43
|
+
* @param orgId - Organization ID, or `null` to skip.
|
|
44
|
+
* @param options - Pagination and filter options.
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```tsx
|
|
48
|
+
* const { ledger, isLoading } = useCreditLedger(orgId, { pageNum: 1 });
|
|
49
|
+
*
|
|
50
|
+
* if (isLoading) return <Skeleton />;
|
|
51
|
+
* if (!ledger) return null;
|
|
52
|
+
*
|
|
53
|
+
* return ledger.entries.map(entry => <LedgerRow key={entry.entryId} entry={entry} />);
|
|
54
|
+
* ```
|
|
55
|
+
*/
|
|
56
|
+
export function useCreditLedger(
|
|
57
|
+
orgId: string | null,
|
|
58
|
+
options: UseCreditLedgerOptions = {},
|
|
59
|
+
): UseCreditLedgerReturn {
|
|
60
|
+
const stigmer = useStigmer();
|
|
61
|
+
const { pageNum = 1, pageSize = 20, typeFilter } = options;
|
|
62
|
+
|
|
63
|
+
const typeFilterKey = typeFilter?.join(",") ?? "";
|
|
64
|
+
|
|
65
|
+
const { data: ledger, isLoading, isRefetching, error, refetch } = useFetch(
|
|
66
|
+
orgId
|
|
67
|
+
? () =>
|
|
68
|
+
stigmer.billing.getCreditLedger({
|
|
69
|
+
orgId,
|
|
70
|
+
page: { num: pageNum, size: pageSize },
|
|
71
|
+
typeFilter,
|
|
72
|
+
})
|
|
73
|
+
: null,
|
|
74
|
+
[orgId, pageNum, pageSize, typeFilterKey, stigmer],
|
|
75
|
+
null as CreditLedgerResponse | null,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
return { ledger, isLoading, isRefetching, error, refetch };
|
|
79
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
CustomerModelPricingResponse,
|
|
5
|
+
} from "@stigmer/protos/ai/stigmer/billing/v1/io_pb";
|
|
6
|
+
import { useStigmer } from "../hooks";
|
|
7
|
+
import { useFetch } from "../internal/useFetch";
|
|
8
|
+
|
|
9
|
+
/** Return value of {@link useCustomerModelPricing}. */
|
|
10
|
+
export interface UseCustomerModelPricingReturn {
|
|
11
|
+
/** The pricing response, or `null` before the first successful fetch. */
|
|
12
|
+
readonly pricing: CustomerModelPricingResponse | null;
|
|
13
|
+
/** `true` while the initial fetch is in flight. */
|
|
14
|
+
readonly isLoading: boolean;
|
|
15
|
+
/** `true` while a background refetch is in flight and stale data is shown. */
|
|
16
|
+
readonly isRefetching: boolean;
|
|
17
|
+
/** Error from the last failed request, or `null` when healthy. */
|
|
18
|
+
readonly error: Error | null;
|
|
19
|
+
/** Discard cached data and re-fetch from the server. */
|
|
20
|
+
readonly refetch: () => void;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Data hook that fetches the customer-facing model price list.
|
|
25
|
+
*
|
|
26
|
+
* Returns per-million-token prices for all billable models with
|
|
27
|
+
* billing policy markup already applied, organized by harness
|
|
28
|
+
* and cost tier.
|
|
29
|
+
*
|
|
30
|
+
* Pass `null` as `orgId` to skip fetching (stable no-op).
|
|
31
|
+
* Pass `undefined` to fetch default pricing (no org override).
|
|
32
|
+
*
|
|
33
|
+
* @param orgId - Organization ID for org-specific overrides,
|
|
34
|
+
* `undefined` for default pricing, or `null` to skip.
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* const { pricing, isLoading } = useCustomerModelPricing(orgId);
|
|
39
|
+
*
|
|
40
|
+
* if (isLoading) return <Skeleton />;
|
|
41
|
+
* if (!pricing) return null;
|
|
42
|
+
*
|
|
43
|
+
* return pricing.entries.map(entry => (
|
|
44
|
+
* <PricingRow key={entry.modelId} entry={entry} />
|
|
45
|
+
* ));
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export function useCustomerModelPricing(
|
|
49
|
+
orgId: string | undefined | null,
|
|
50
|
+
): UseCustomerModelPricingReturn {
|
|
51
|
+
const stigmer = useStigmer();
|
|
52
|
+
|
|
53
|
+
const skip = orgId === null;
|
|
54
|
+
|
|
55
|
+
const { data: pricing, isLoading, isRefetching, error, refetch } = useFetch(
|
|
56
|
+
skip
|
|
57
|
+
? null
|
|
58
|
+
: () =>
|
|
59
|
+
stigmer.billing.getCustomerModelPricing(
|
|
60
|
+
orgId ? { orgId } : undefined,
|
|
61
|
+
),
|
|
62
|
+
[orgId, stigmer],
|
|
63
|
+
null as CustomerModelPricingResponse | null,
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
return { pricing, isLoading, isRefetching, error, refetch };
|
|
67
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { useStigmer } from "../hooks";
|
|
5
|
+
import { toError } from "../internal/toError";
|
|
6
|
+
import type { BillingAccount } from "@stigmer/protos/ai/stigmer/billing/v1/billing_account_pb";
|
|
7
|
+
|
|
8
|
+
/** Input for {@link useSetAutoRechargeConfig}. */
|
|
9
|
+
export interface SetAutoRechargeConfigInput {
|
|
10
|
+
/** Organization ID to configure auto-recharge for. */
|
|
11
|
+
readonly orgId: string;
|
|
12
|
+
/** Whether auto-recharge is enabled. */
|
|
13
|
+
readonly enabled: boolean;
|
|
14
|
+
/** Trigger threshold in micro-USD. */
|
|
15
|
+
readonly thresholdMicros: bigint;
|
|
16
|
+
/** Fixed charge per recharge event in micro-USD. */
|
|
17
|
+
readonly rechargeAmountMicros: bigint;
|
|
18
|
+
/** Maximum monthly auto-recharge spend in micro-USD. */
|
|
19
|
+
readonly monthlyCapMicros: bigint;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Return value of {@link useSetAutoRechargeConfig}. */
|
|
23
|
+
export interface UseSetAutoRechargeConfigReturn {
|
|
24
|
+
/**
|
|
25
|
+
* Save auto-recharge configuration. Returns the updated BillingAccount
|
|
26
|
+
* on success.
|
|
27
|
+
*/
|
|
28
|
+
readonly setConfig: (input: SetAutoRechargeConfigInput) => Promise<BillingAccount>;
|
|
29
|
+
/** `true` while the configuration is being saved. */
|
|
30
|
+
readonly isSubmitting: boolean;
|
|
31
|
+
/** Error from the last failed attempt, or `null` when healthy. */
|
|
32
|
+
readonly error: Error | null;
|
|
33
|
+
/** Reset `error` to `null`. */
|
|
34
|
+
readonly clearError: () => void;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Behavior hook for configuring auto-recharge settings.
|
|
39
|
+
*
|
|
40
|
+
* Wraps `billing.setAutoRechargeConfig` with loading and error state
|
|
41
|
+
* management. Returns the updated `BillingAccount` on success so the
|
|
42
|
+
* parent can refresh its cached data.
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* const { setConfig, isSubmitting, error } = useSetAutoRechargeConfig();
|
|
47
|
+
*
|
|
48
|
+
* await setConfig({
|
|
49
|
+
* orgId,
|
|
50
|
+
* enabled: true,
|
|
51
|
+
* thresholdMicros: BigInt(5_000_000),
|
|
52
|
+
* rechargeAmountMicros: BigInt(50_000_000),
|
|
53
|
+
* monthlyCapMicros: BigInt(200_000_000),
|
|
54
|
+
* });
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function useSetAutoRechargeConfig(): UseSetAutoRechargeConfigReturn {
|
|
58
|
+
const stigmer = useStigmer();
|
|
59
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
60
|
+
const [error, setError] = useState<Error | null>(null);
|
|
61
|
+
|
|
62
|
+
const clearError = useCallback(() => setError(null), []);
|
|
63
|
+
|
|
64
|
+
const setConfig = useCallback(
|
|
65
|
+
async (input: SetAutoRechargeConfigInput): Promise<BillingAccount> => {
|
|
66
|
+
setIsSubmitting(true);
|
|
67
|
+
setError(null);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const account = await stigmer.billing.setAutoRechargeConfig({
|
|
71
|
+
orgId: input.orgId,
|
|
72
|
+
enabled: input.enabled,
|
|
73
|
+
thresholdMicros: input.thresholdMicros,
|
|
74
|
+
rechargeAmountMicros: input.rechargeAmountMicros,
|
|
75
|
+
monthlyCapMicros: input.monthlyCapMicros,
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
return account;
|
|
79
|
+
} catch (err) {
|
|
80
|
+
setError(toError(err));
|
|
81
|
+
throw err;
|
|
82
|
+
} finally {
|
|
83
|
+
setIsSubmitting(false);
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
[stigmer],
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
return { setConfig, isSubmitting, error, clearError };
|
|
90
|
+
}
|
|
@@ -97,7 +97,7 @@ export function ComposerToolbar({
|
|
|
97
97
|
const hasTier2 = configureItems.length > 0;
|
|
98
98
|
const showHarnessSeparate = showHarnessSelector && !showModelSelector;
|
|
99
99
|
const hasExecParams = showHarnessSeparate || showModelSelector;
|
|
100
|
-
const harnessLocked = harness !== undefined
|
|
100
|
+
const harnessLocked = harness !== undefined;
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
103
|
<div className="flex items-center justify-between gap-2 border-t border-border-muted px-3 py-2">
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useMemo, useRef, useState, type DragEvent, type KeyboardEvent } from "react";
|
|
3
|
+
import { memo, useCallback, useEffect, useMemo, useRef, useState, type DragEvent, type KeyboardEvent } from "react";
|
|
4
4
|
import { cn } from "@stigmer/theme";
|
|
5
5
|
import { getUserMessage, type AttachmentInput, type EnvVarInput, type McpServerUsageInput, type ResourceRef } from "@stigmer/sdk";
|
|
6
6
|
import { useComposer } from "./useComposer";
|
|
@@ -33,6 +33,7 @@ import {
|
|
|
33
33
|
SYSTEM_ENV_VAR_KEYS,
|
|
34
34
|
resolveSystemEnvVarValues,
|
|
35
35
|
} from "../environment/systemEnvVars";
|
|
36
|
+
import { useRenderTracer } from "../internal/dev";
|
|
36
37
|
import { RunnerPhase } from "@stigmer/protos/ai/stigmer/agentic/runner/v1/enum_pb";
|
|
37
38
|
import {
|
|
38
39
|
isActivePhase,
|
|
@@ -371,7 +372,7 @@ export interface SessionComposerProps {
|
|
|
371
372
|
* />
|
|
372
373
|
* ```
|
|
373
374
|
*/
|
|
374
|
-
export function SessionComposer({
|
|
375
|
+
export const SessionComposer = memo(function SessionComposer({
|
|
375
376
|
onSubmit,
|
|
376
377
|
isSubmitting = false,
|
|
377
378
|
disabled = false,
|
|
@@ -407,7 +408,24 @@ export function SessionComposer({
|
|
|
407
408
|
ariaLabel = "Send message",
|
|
408
409
|
className,
|
|
409
410
|
}: SessionComposerProps) {
|
|
410
|
-
|
|
411
|
+
useRenderTracer("SessionComposer", { disabled, isSubmitting });
|
|
412
|
+
|
|
413
|
+
const [modelId, setModelIdRaw] = useState<string | undefined>(defaultModelId);
|
|
414
|
+
const userOverrodeModel = useRef(false);
|
|
415
|
+
|
|
416
|
+
// Sync internal modelId when the external defaultModelId prop changes
|
|
417
|
+
// (e.g., lastExecModelId resolves after executions load). Only sync if the
|
|
418
|
+
// user hasn't made a local selection in this composer instance.
|
|
419
|
+
useEffect(() => {
|
|
420
|
+
if (!userOverrodeModel.current && defaultModelId !== undefined) {
|
|
421
|
+
setModelIdRaw(defaultModelId);
|
|
422
|
+
}
|
|
423
|
+
}, [defaultModelId]);
|
|
424
|
+
|
|
425
|
+
const setModelId = useCallback((id: string | undefined) => {
|
|
426
|
+
userOverrodeModel.current = true;
|
|
427
|
+
setModelIdRaw(id);
|
|
428
|
+
}, []);
|
|
411
429
|
|
|
412
430
|
const [displayNames, setDisplayNames] = useState<Map<string, string>>(
|
|
413
431
|
() => new Map(),
|
|
@@ -1418,7 +1436,7 @@ export function SessionComposer({
|
|
|
1418
1436
|
</div>
|
|
1419
1437
|
</div>
|
|
1420
1438
|
);
|
|
1421
|
-
}
|
|
1439
|
+
});
|
|
1422
1440
|
|
|
1423
1441
|
// ---------------------------------------------------------------------------
|
|
1424
1442
|
// Agent setup error — secret-flow guidance or generic fallback
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { describe, it, expect } from "vitest";
|
|
2
|
+
import { SessionComposer } from "../SessionComposer";
|
|
3
|
+
|
|
4
|
+
describe("SessionComposer — memo isolation", () => {
|
|
5
|
+
it("is wrapped in React.memo (shallow prop comparison)", () => {
|
|
6
|
+
// React.memo returns an exotic component with $$typeof set to
|
|
7
|
+
// Symbol.for("react.memo") and a `type` field pointing at the
|
|
8
|
+
// inner function. Regular function components have neither.
|
|
9
|
+
const memoSymbol = Symbol.for("react.memo");
|
|
10
|
+
const typed = SessionComposer as unknown as { $$typeof: symbol; type: Function; compare: unknown };
|
|
11
|
+
|
|
12
|
+
expect(typed.$$typeof).toBe(memoSymbol);
|
|
13
|
+
expect(typeof typed.type).toBe("function");
|
|
14
|
+
// The transform may rename the inner function to avoid shadowing
|
|
15
|
+
// the outer `const SessionComposer` binding (e.g. "SessionComposer2").
|
|
16
|
+
expect(typed.type.name).toMatch(/^SessionComposer/);
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
it("uses default shallow comparison (no custom areEqual)", () => {
|
|
20
|
+
const typed = SessionComposer as unknown as { compare: unknown };
|
|
21
|
+
|
|
22
|
+
// When React.memo is called without a second argument, `compare`
|
|
23
|
+
// is null — React falls back to shallow prop comparison.
|
|
24
|
+
expect(typed.compare).toBeNull();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useCallback, useEffect, useMemo, useState } from "react";
|
|
3
|
+
import { memo, useCallback, useEffect, useMemo, useState } from "react";
|
|
4
4
|
import type { PendingApproval } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/approval_pb";
|
|
5
5
|
import { ApprovalAction } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
6
6
|
import { cn } from "@stigmer/theme";
|
|
@@ -39,6 +39,10 @@ export interface ApprovalCardProps {
|
|
|
39
39
|
* dispatch, ensuring pixel-level parity between the approval
|
|
40
40
|
* preview and the post-execution detail view.
|
|
41
41
|
*
|
|
42
|
+
* Wrapped in `React.memo` — structural sharing (T04) preserves the
|
|
43
|
+
* `PendingApproval` reference when unchanged, so approval cards
|
|
44
|
+
* skip re-renders during unrelated stream updates.
|
|
45
|
+
*
|
|
42
46
|
* @example
|
|
43
47
|
* ```tsx
|
|
44
48
|
* <ApprovalCard
|
|
@@ -48,7 +52,7 @@ export interface ApprovalCardProps {
|
|
|
48
52
|
* />
|
|
49
53
|
* ```
|
|
50
54
|
*/
|
|
51
|
-
export function ApprovalCard({
|
|
55
|
+
export const ApprovalCard = memo(function ApprovalCard({
|
|
52
56
|
pendingApproval,
|
|
53
57
|
onSubmit,
|
|
54
58
|
isSubmitting = false,
|
|
@@ -198,7 +202,7 @@ export function ApprovalCard({
|
|
|
198
202
|
</div>
|
|
199
203
|
</div>
|
|
200
204
|
);
|
|
201
|
-
}
|
|
205
|
+
});
|
|
202
206
|
|
|
203
207
|
// ---------------------------------------------------------------------------
|
|
204
208
|
// Internal sub-components
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
+
import { memo } from "react";
|
|
3
4
|
import { ExecutionPhase } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
4
5
|
import { cn } from "@stigmer/theme";
|
|
5
6
|
|
|
@@ -97,7 +98,7 @@ const PHASE_CONFIG: ReadonlyMap<ExecutionPhase, PhaseConfig> = new Map([
|
|
|
97
98
|
* <ExecutionPhaseBadge phase={ExecutionPhase.EXECUTION_COMPLETED} />
|
|
98
99
|
* ```
|
|
99
100
|
*/
|
|
100
|
-
export function ExecutionPhaseBadge({
|
|
101
|
+
export const ExecutionPhaseBadge = memo(function ExecutionPhaseBadge({
|
|
101
102
|
phase,
|
|
102
103
|
className,
|
|
103
104
|
}: ExecutionPhaseBadgeProps) {
|
|
@@ -122,7 +123,7 @@ export function ExecutionPhaseBadge({
|
|
|
122
123
|
{config.label}
|
|
123
124
|
</span>
|
|
124
125
|
);
|
|
125
|
-
}
|
|
126
|
+
});
|
|
126
127
|
|
|
127
128
|
function DotIcon() {
|
|
128
129
|
return (
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
|
-
import { useState } from "react";
|
|
4
|
-
import
|
|
3
|
+
import { memo, useState } from "react";
|
|
4
|
+
import { Streamdown } from "streamdown";
|
|
5
5
|
import type { AgentMessage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/message_pb";
|
|
6
6
|
import { MessageType } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
7
7
|
import { cn } from "@stigmer/theme";
|
|
8
|
-
import { MARKDOWN_COMPONENTS
|
|
8
|
+
import { MARKDOWN_COMPONENTS } from "../internal/markdown-components";
|
|
9
|
+
import { useRenderTracer } from "../internal/dev";
|
|
9
10
|
|
|
10
11
|
/** Props for {@link MessageEntry}. */
|
|
11
12
|
export interface MessageEntryProps {
|
|
@@ -19,14 +20,18 @@ export interface MessageEntryProps {
|
|
|
19
20
|
* Renders a single message in the conversation thread.
|
|
20
21
|
*
|
|
21
22
|
* - `MESSAGE_HUMAN` — plain text with muted background
|
|
22
|
-
* - `MESSAGE_AI` — markdown-rendered via
|
|
23
|
-
*
|
|
23
|
+
* - `MESSAGE_AI` — markdown-rendered via Streamdown with block-level
|
|
24
|
+
* memoization and streaming-aware incomplete-syntax healing
|
|
24
25
|
* - `MESSAGE_THINKING` — collapsible thinking block with subdued styling,
|
|
25
26
|
* collapsed by default showing a brief summary
|
|
26
27
|
* - `MESSAGE_SYSTEM` — small muted text
|
|
27
28
|
* - `MESSAGE_TOOL` / `UNSPECIFIED` — renders nothing (tool results are
|
|
28
29
|
* consumed by {@link ToolCallGroup})
|
|
29
30
|
*
|
|
31
|
+
* Wrapped in `React.memo` — structural sharing (T04) guarantees that
|
|
32
|
+
* unchanged messages keep the same object reference, so completed
|
|
33
|
+
* messages skip re-renders entirely during streaming.
|
|
34
|
+
*
|
|
30
35
|
* Purely presentational — no data fetching, no state.
|
|
31
36
|
* All visual properties flow through `--stgm-*` tokens.
|
|
32
37
|
*
|
|
@@ -35,7 +40,16 @@ export interface MessageEntryProps {
|
|
|
35
40
|
* <MessageEntry message={agentMessage} />
|
|
36
41
|
* ```
|
|
37
42
|
*/
|
|
38
|
-
export
|
|
43
|
+
export const MessageEntry = memo(function MessageEntry({
|
|
44
|
+
message,
|
|
45
|
+
className,
|
|
46
|
+
}: MessageEntryProps) {
|
|
47
|
+
useRenderTracer("MessageEntry", {
|
|
48
|
+
messageType: message.type,
|
|
49
|
+
contentLength: message.content.length,
|
|
50
|
+
isStreaming: message.isStreaming,
|
|
51
|
+
});
|
|
52
|
+
|
|
39
53
|
switch (message.type) {
|
|
40
54
|
case MessageType.MESSAGE_HUMAN:
|
|
41
55
|
return <HumanMessage content={message.content} className={className} />;
|
|
@@ -60,7 +74,7 @@ export function MessageEntry({ message, className }: MessageEntryProps) {
|
|
|
60
74
|
default:
|
|
61
75
|
return null;
|
|
62
76
|
}
|
|
63
|
-
}
|
|
77
|
+
});
|
|
64
78
|
|
|
65
79
|
function HumanMessage({
|
|
66
80
|
content,
|
|
@@ -89,6 +103,8 @@ function AiMessage({
|
|
|
89
103
|
isStreaming: boolean;
|
|
90
104
|
className?: string;
|
|
91
105
|
}) {
|
|
106
|
+
useRenderTracer("AiMessage", { contentLength: content.length, isStreaming });
|
|
107
|
+
|
|
92
108
|
return (
|
|
93
109
|
<div
|
|
94
110
|
role="article"
|
|
@@ -97,18 +113,13 @@ function AiMessage({
|
|
|
97
113
|
className={cn("px-4 py-3", className)}
|
|
98
114
|
>
|
|
99
115
|
<div className="stgm-prose">
|
|
100
|
-
<
|
|
101
|
-
remarkPlugins={REMARK_PLUGINS}
|
|
116
|
+
<Streamdown
|
|
102
117
|
components={MARKDOWN_COMPONENTS}
|
|
118
|
+
isAnimating={isStreaming}
|
|
119
|
+
caret="block"
|
|
103
120
|
>
|
|
104
121
|
{content}
|
|
105
|
-
</
|
|
106
|
-
{isStreaming && (
|
|
107
|
-
<span
|
|
108
|
-
className="inline-block w-[2px] h-[1em] bg-foreground align-text-bottom animate-pulse ml-0.5"
|
|
109
|
-
aria-hidden="true"
|
|
110
|
-
/>
|
|
111
|
-
)}
|
|
122
|
+
</Streamdown>
|
|
112
123
|
</div>
|
|
113
124
|
</div>
|
|
114
125
|
);
|