@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
|
@@ -17,6 +17,7 @@ import type {
|
|
|
17
17
|
} from "@stigmer/sdk";
|
|
18
18
|
import { isTerminalPhase } from "../execution/execution-phases";
|
|
19
19
|
import { useStigmer } from "../hooks";
|
|
20
|
+
import { useConversationStoreRef } from "../internal/store";
|
|
20
21
|
import { useCreateAgentExecution } from "../execution/useCreateAgentExecution";
|
|
21
22
|
import { useExecutionStream } from "../execution/useExecutionStream";
|
|
22
23
|
import { useSubmitApproval } from "../execution/useSubmitApproval";
|
|
@@ -248,7 +249,14 @@ export function useSessionConversation(
|
|
|
248
249
|
|
|
249
250
|
const activeExecutionId = pendingExecutionId ?? listActiveId;
|
|
250
251
|
|
|
251
|
-
|
|
252
|
+
// The conversation store is shared between useExecutionStream (which
|
|
253
|
+
// ingests snapshots with structural sharing + rAF coalescing) and the
|
|
254
|
+
// rendering tree. This eliminates the duplicate structuralShare that
|
|
255
|
+
// was previously done in this hook.
|
|
256
|
+
const conversationStore = useConversationStoreRef();
|
|
257
|
+
const stream = useExecutionStream(activeExecutionId, {
|
|
258
|
+
store: conversationStore,
|
|
259
|
+
});
|
|
252
260
|
|
|
253
261
|
// Clear pendingExecutionId once the execution appears in the fetched list
|
|
254
262
|
useEffect(() => {
|
|
@@ -291,7 +299,8 @@ export function useSessionConversation(
|
|
|
291
299
|
);
|
|
292
300
|
}, [executions, activeExecutionId]);
|
|
293
301
|
|
|
294
|
-
const activeStreamExecution =
|
|
302
|
+
const activeStreamExecution =
|
|
303
|
+
stream.execution ?? fetchedActiveExecution;
|
|
295
304
|
|
|
296
305
|
const activePhase = useMemo<ExecutionPhase | null>(() => {
|
|
297
306
|
if (!activeExecutionId) return null;
|
|
@@ -253,7 +253,7 @@ export function useSessionPageFlow(
|
|
|
253
253
|
|
|
254
254
|
sessionVariables.clear();
|
|
255
255
|
},
|
|
256
|
-
[conv, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables, resolution, agentRef, sessionInstanceId, stigmer],
|
|
256
|
+
[conv.sendFollowUp, modelId, workspace, mcpServerUsages, skillRefs, sessionVariables.clear, resolution, agentRef, sessionInstanceId, stigmer],
|
|
257
257
|
);
|
|
258
258
|
|
|
259
259
|
// -------------------------------------------------------------------------
|
|
@@ -1,27 +1,33 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useMemo } from "react";
|
|
4
|
+
import { create } from "@bufbuild/protobuf";
|
|
4
5
|
import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
|
|
5
|
-
import {
|
|
6
|
-
|
|
6
|
+
import {
|
|
7
|
+
GetSessionUsageReportInputSchema,
|
|
8
|
+
type GetSessionUsageReportOutput,
|
|
9
|
+
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
|
|
10
|
+
import type { ModelUsage } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/usage_pb";
|
|
11
|
+
import { useStigmer } from "../hooks";
|
|
12
|
+
import { useFetch } from "../internal/useFetch";
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
|
-
* Per-model cost breakdown
|
|
15
|
+
* Per-model cost breakdown.
|
|
10
16
|
*/
|
|
11
17
|
export interface ModelCostEntry {
|
|
12
|
-
/** Model identifier (e.g
|
|
18
|
+
/** Model identifier (e.g. "claude-sonnet-4-20250514"). */
|
|
13
19
|
readonly model: string;
|
|
14
|
-
/** Provider
|
|
20
|
+
/** Provider name (e.g. "anthropic", "openai"). */
|
|
15
21
|
readonly provider: string;
|
|
16
|
-
/** Estimated cost in USD for
|
|
22
|
+
/** Estimated cost in USD for this model's usage. */
|
|
17
23
|
readonly estimatedCostUsd: number;
|
|
18
|
-
/** Total
|
|
24
|
+
/** Total input tokens consumed by this model. */
|
|
19
25
|
readonly inputTokens: number;
|
|
20
|
-
/** Total output tokens
|
|
26
|
+
/** Total output tokens generated by this model. */
|
|
21
27
|
readonly outputTokens: number;
|
|
22
|
-
/**
|
|
28
|
+
/** Tokens used to create cache entries. */
|
|
23
29
|
readonly cacheCreationTokens: number;
|
|
24
|
-
/**
|
|
30
|
+
/** Tokens served from cache. */
|
|
25
31
|
readonly cacheReadTokens: number;
|
|
26
32
|
/** Number of LLM calls made to this model. */
|
|
27
33
|
readonly callCount: number;
|
|
@@ -29,140 +35,113 @@ export interface ModelCostEntry {
|
|
|
29
35
|
|
|
30
36
|
/** Return value of {@link useSessionUsage}. */
|
|
31
37
|
export interface UseSessionUsageReturn {
|
|
32
|
-
/**
|
|
38
|
+
/** Aggregate estimated cost in USD across all models. */
|
|
33
39
|
readonly totalCostUsd: number;
|
|
34
|
-
/** Total tokens (
|
|
40
|
+
/** Total tokens (input + output) across all models. */
|
|
35
41
|
readonly totalTokens: number;
|
|
36
|
-
/** Total input tokens
|
|
42
|
+
/** Total input tokens across all models. */
|
|
37
43
|
readonly inputTokens: number;
|
|
38
|
-
/** Total output tokens across all
|
|
44
|
+
/** Total output tokens across all models. */
|
|
39
45
|
readonly outputTokens: number;
|
|
40
|
-
/** Total
|
|
46
|
+
/** Total tokens served from cache across all models. */
|
|
41
47
|
readonly cacheReadTokens: number;
|
|
42
|
-
/** Total cache
|
|
48
|
+
/** Total tokens used to create cache entries across all models. */
|
|
43
49
|
readonly cacheCreationTokens: number;
|
|
44
|
-
/** Total number of LLM calls
|
|
50
|
+
/** Total number of LLM calls in this session. */
|
|
45
51
|
readonly llmCallCount: number;
|
|
46
|
-
/** Per-model
|
|
52
|
+
/** Per-model cost and token breakdown. */
|
|
47
53
|
readonly modelBreakdown: readonly ModelCostEntry[];
|
|
48
|
-
/**
|
|
54
|
+
/** Model with the highest usage in this session. */
|
|
49
55
|
readonly primaryModel: string;
|
|
50
|
-
/**
|
|
56
|
+
/** Provider of the primary model. */
|
|
51
57
|
readonly primaryProvider: string;
|
|
52
|
-
/** `true` when
|
|
58
|
+
/** `true` when usage data is available. */
|
|
53
59
|
readonly hasUsage: boolean;
|
|
54
60
|
}
|
|
55
61
|
|
|
62
|
+
const EMPTY: UseSessionUsageReturn = {
|
|
63
|
+
totalCostUsd: 0,
|
|
64
|
+
totalTokens: 0,
|
|
65
|
+
inputTokens: 0,
|
|
66
|
+
outputTokens: 0,
|
|
67
|
+
cacheReadTokens: 0,
|
|
68
|
+
cacheCreationTokens: 0,
|
|
69
|
+
llmCallCount: 0,
|
|
70
|
+
modelBreakdown: [],
|
|
71
|
+
primaryModel: "",
|
|
72
|
+
primaryProvider: "",
|
|
73
|
+
hasUsage: false,
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
function microsToUsd(micros: bigint): number {
|
|
77
|
+
return Number(micros) / 1_000_000;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function mapModelUsage(m: ModelUsage): ModelCostEntry {
|
|
81
|
+
return {
|
|
82
|
+
model: m.model,
|
|
83
|
+
provider: m.provider,
|
|
84
|
+
estimatedCostUsd: microsToUsd(m.billableCostMicros),
|
|
85
|
+
inputTokens: Number(m.inputTokens),
|
|
86
|
+
outputTokens: Number(m.outputTokens),
|
|
87
|
+
cacheCreationTokens: Number(m.cacheCreationInputTokens),
|
|
88
|
+
cacheReadTokens: Number(m.cacheReadInputTokens),
|
|
89
|
+
callCount: m.callCount,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function mapReport(report: GetSessionUsageReportOutput): UseSessionUsageReturn {
|
|
94
|
+
const agg = report.totalUsage;
|
|
95
|
+
if (!agg) return EMPTY;
|
|
96
|
+
|
|
97
|
+
return {
|
|
98
|
+
totalCostUsd: microsToUsd(agg.billableCostMicros),
|
|
99
|
+
totalTokens: Number(agg.totalTokens),
|
|
100
|
+
inputTokens: Number(agg.inputTokens),
|
|
101
|
+
outputTokens: Number(agg.outputTokens),
|
|
102
|
+
cacheReadTokens: Number(agg.cacheReadInputTokens),
|
|
103
|
+
cacheCreationTokens: Number(agg.cacheCreationInputTokens),
|
|
104
|
+
llmCallCount: agg.llmCallCount,
|
|
105
|
+
modelBreakdown: report.modelBreakdown.map(mapModelUsage),
|
|
106
|
+
primaryModel: agg.primaryModel,
|
|
107
|
+
primaryProvider: agg.primaryProvider,
|
|
108
|
+
hasUsage: true,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
56
112
|
/**
|
|
57
|
-
*
|
|
58
|
-
* in a session from per-message {@link LlmCallMetrics}.
|
|
113
|
+
* Usage hook for session-level cost and token aggregation.
|
|
59
114
|
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
115
|
+
* Calls `getSessionUsageReport` to fetch real usage data from the
|
|
116
|
+
* billing domain. Returns zeros while loading or when no session is
|
|
117
|
+
* available.
|
|
63
118
|
*
|
|
64
|
-
*
|
|
65
|
-
* the single source of truth for cost data. This hook walks all messages
|
|
66
|
-
* (main agent + sub-agents) across all executions and sums the fields.
|
|
67
|
-
*
|
|
68
|
-
* @param executions - All executions for a session, in chronological
|
|
69
|
-
* order. Pass both completed and active-stream executions.
|
|
70
|
-
*
|
|
71
|
-
* @example
|
|
72
|
-
* ```tsx
|
|
73
|
-
* const conv = useSessionConversation(sessionId, org);
|
|
74
|
-
* const allExecutions = [
|
|
75
|
-
* ...conv.completedExecutions,
|
|
76
|
-
* ...(conv.activeStreamExecution ? [conv.activeStreamExecution] : []),
|
|
77
|
-
* ];
|
|
78
|
-
* const { totalCostUsd, totalTokens, hasUsage } = useSessionUsage(allExecutions);
|
|
79
|
-
* ```
|
|
119
|
+
* @param executions - All executions for a session (used to derive session ID).
|
|
80
120
|
*/
|
|
81
121
|
export function useSessionUsage(
|
|
82
122
|
executions: readonly AgentExecution[],
|
|
83
123
|
): UseSessionUsageReturn {
|
|
84
|
-
|
|
85
|
-
let totalCostUsd = 0;
|
|
86
|
-
let totalTokens = 0;
|
|
87
|
-
let inputTokens = 0;
|
|
88
|
-
let outputTokens = 0;
|
|
89
|
-
let cacheReadTokens = 0;
|
|
90
|
-
let cacheCreationTokens = 0;
|
|
91
|
-
let llmCallCount = 0;
|
|
92
|
-
let primaryModel = "";
|
|
93
|
-
let primaryProvider = "";
|
|
94
|
-
const modelMap = new Map<string, ModelCostEntry>();
|
|
95
|
-
|
|
96
|
-
const processMessage = (msg: { type: MessageType; llmMetrics?: LlmCallMetrics }) => {
|
|
97
|
-
const m = msg.llmMetrics;
|
|
98
|
-
if (!m) return;
|
|
124
|
+
const stigmer = useStigmer();
|
|
99
125
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
cacheReadTokens += m.cacheReadTokens;
|
|
105
|
-
cacheCreationTokens += m.cacheCreationTokens;
|
|
106
|
-
llmCallCount++;
|
|
126
|
+
const sessionId = useMemo(
|
|
127
|
+
() => executions[0]?.spec?.sessionId ?? null,
|
|
128
|
+
[executions],
|
|
129
|
+
);
|
|
107
130
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
131
|
+
const { data: report } = useFetch(
|
|
132
|
+
sessionId
|
|
133
|
+
? () =>
|
|
134
|
+
stigmer.agentExecution.getSessionUsageReport(
|
|
135
|
+
create(GetSessionUsageReportInputSchema, { sessionId }),
|
|
136
|
+
)
|
|
137
|
+
: null,
|
|
138
|
+
[sessionId, stigmer],
|
|
139
|
+
null as GetSessionUsageReportOutput | null,
|
|
140
|
+
{ cacheKey: sessionId ? `session-usage:${sessionId}` : undefined },
|
|
141
|
+
);
|
|
112
142
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
...existing,
|
|
118
|
-
estimatedCostUsd: existing.estimatedCostUsd + m.estimatedCostUsd,
|
|
119
|
-
inputTokens: existing.inputTokens + m.inputTokens,
|
|
120
|
-
outputTokens: existing.outputTokens + m.outputTokens,
|
|
121
|
-
cacheCreationTokens: existing.cacheCreationTokens + m.cacheCreationTokens,
|
|
122
|
-
cacheReadTokens: existing.cacheReadTokens + m.cacheReadTokens,
|
|
123
|
-
callCount: existing.callCount + 1,
|
|
124
|
-
});
|
|
125
|
-
} else {
|
|
126
|
-
modelMap.set(key, {
|
|
127
|
-
model: m.model,
|
|
128
|
-
provider: m.provider,
|
|
129
|
-
estimatedCostUsd: m.estimatedCostUsd,
|
|
130
|
-
inputTokens: m.inputTokens,
|
|
131
|
-
outputTokens: m.outputTokens,
|
|
132
|
-
cacheCreationTokens: m.cacheCreationTokens,
|
|
133
|
-
cacheReadTokens: m.cacheReadTokens,
|
|
134
|
-
callCount: 1,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
for (const execution of executions) {
|
|
140
|
-
for (const msg of execution.status?.messages ?? []) {
|
|
141
|
-
processMessage(msg);
|
|
142
|
-
}
|
|
143
|
-
for (const sub of execution.status?.subAgentExecutions ?? []) {
|
|
144
|
-
for (const msg of sub.messages) {
|
|
145
|
-
processMessage(msg);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
const modelBreakdown = Array.from(modelMap.values()).sort(
|
|
151
|
-
(a, b) => b.estimatedCostUsd - a.estimatedCostUsd,
|
|
152
|
-
);
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
totalCostUsd,
|
|
156
|
-
totalTokens,
|
|
157
|
-
inputTokens,
|
|
158
|
-
outputTokens,
|
|
159
|
-
cacheReadTokens,
|
|
160
|
-
cacheCreationTokens,
|
|
161
|
-
llmCallCount,
|
|
162
|
-
modelBreakdown,
|
|
163
|
-
primaryModel,
|
|
164
|
-
primaryProvider,
|
|
165
|
-
hasUsage: llmCallCount > 0,
|
|
166
|
-
};
|
|
167
|
-
}, [executions]);
|
|
143
|
+
return useMemo(() => {
|
|
144
|
+
if (!report) return EMPTY;
|
|
145
|
+
return mapReport(report);
|
|
146
|
+
}, [report]);
|
|
168
147
|
}
|
package/src/settings/index.ts
CHANGED
|
@@ -2,6 +2,8 @@ export { SETTINGS_NAV_GROUPS } from "./settings-nav";
|
|
|
2
2
|
export type { SettingsNavItem, SettingsNavGroup } from "./settings-nav";
|
|
3
3
|
|
|
4
4
|
export { ApiKeysSection } from "./ApiKeysSection";
|
|
5
|
+
export { BillingSection } from "./BillingSection";
|
|
6
|
+
export type { BillingSectionProps } from "./BillingSection";
|
|
5
7
|
export { MembersSection } from "./MembersSection";
|
|
6
8
|
export { OrgProfileSection } from "./OrgProfileSection";
|
|
7
9
|
export { EnvironmentsSection } from "./EnvironmentsSection";
|
|
@@ -69,7 +69,7 @@ export const SETTINGS_NAV_GROUPS: readonly SettingsNavGroup[] = [
|
|
|
69
69
|
},
|
|
70
70
|
{
|
|
71
71
|
label: "Billing & Usage",
|
|
72
|
-
description: "
|
|
72
|
+
description: "Credit management and usage metrics.",
|
|
73
73
|
items: [
|
|
74
74
|
{ href: "/settings/billing", label: "Billing", icon: CreditCard },
|
|
75
75
|
{ href: "/settings/usage", label: "Usage", icon: BarChart3 },
|
package/src/styles.css
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
@source "./**/*.{ts,tsx}";
|
|
2
|
+
@source "../node_modules/streamdown/dist/*.js";
|
|
2
3
|
|
|
3
4
|
@layer stgm;
|
|
4
5
|
|
|
@@ -82,6 +83,8 @@
|
|
|
82
83
|
|
|
83
84
|
@layer stgm {
|
|
84
85
|
.stgm {
|
|
86
|
+
--stgm-motion-duration: 150ms;
|
|
87
|
+
--stgm-motion-easing: var(--stgm-transition-timing, ease-out);
|
|
85
88
|
line-height: 1.5;
|
|
86
89
|
-webkit-font-smoothing: antialiased;
|
|
87
90
|
-moz-osx-font-smoothing: grayscale;
|
|
@@ -95,4 +98,32 @@
|
|
|
95
98
|
border-style: solid;
|
|
96
99
|
border-color: var(--stgm-border, currentColor);
|
|
97
100
|
}
|
|
101
|
+
|
|
102
|
+
@keyframes stgm-fade-in-up {
|
|
103
|
+
from {
|
|
104
|
+
opacity: 0;
|
|
105
|
+
transform: translateY(6px);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.stgm-thread-item-enter {
|
|
110
|
+
animation: stgm-fade-in-up var(--stgm-motion-duration) var(--stgm-motion-easing) both;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@layer stgm {
|
|
115
|
+
@media (prefers-reduced-motion: reduce) {
|
|
116
|
+
.stgm {
|
|
117
|
+
--stgm-motion-duration: 0ms;
|
|
118
|
+
--stgm-transition-duration: 0ms;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.stgm *,
|
|
122
|
+
.stgm *::before,
|
|
123
|
+
.stgm *::after {
|
|
124
|
+
animation-duration: 0.01ms !important;
|
|
125
|
+
animation-iteration-count: 1 !important;
|
|
126
|
+
transition-duration: 0.01ms !important;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
98
129
|
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stigmer/theme";
|
|
4
|
+
import type { AgentUsageSummary } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
|
|
5
|
+
import { formatCost } from "../execution/UsageWidget";
|
|
6
|
+
|
|
7
|
+
/** Props for {@link AgentBreakdownList}. */
|
|
8
|
+
export interface AgentBreakdownListProps {
|
|
9
|
+
/** Top agents by cost, ordered by billable cost descending. */
|
|
10
|
+
readonly agents: readonly AgentUsageSummary[];
|
|
11
|
+
/** Total billable cost for the org (used to compute percentages). */
|
|
12
|
+
readonly totalBillableCostMicros: bigint;
|
|
13
|
+
/** Optional href builder for agent links. Receives the agent ID. */
|
|
14
|
+
readonly agentHref?: (agentId: string) => string;
|
|
15
|
+
/** Additional CSS class names. */
|
|
16
|
+
readonly className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Renders a ranked list of agents by cost with proportional cost bars.
|
|
21
|
+
*
|
|
22
|
+
* Each row shows the agent name, execution count, token usage,
|
|
23
|
+
* billable cost, and a visual bar representing cost as a percentage
|
|
24
|
+
* of the organization total.
|
|
25
|
+
*/
|
|
26
|
+
export function AgentBreakdownList({
|
|
27
|
+
agents,
|
|
28
|
+
totalBillableCostMicros,
|
|
29
|
+
agentHref,
|
|
30
|
+
className,
|
|
31
|
+
}: AgentBreakdownListProps) {
|
|
32
|
+
if (agents.length === 0) return null;
|
|
33
|
+
|
|
34
|
+
const totalCost = Number(totalBillableCostMicros);
|
|
35
|
+
const maxCost =
|
|
36
|
+
agents.length > 0 ? Number(agents[0].billableCostMicros) : 0;
|
|
37
|
+
|
|
38
|
+
return (
|
|
39
|
+
<div className={className}>
|
|
40
|
+
<h3 className="mb-2 text-xs font-semibold text-foreground">
|
|
41
|
+
Top Agents by Cost
|
|
42
|
+
</h3>
|
|
43
|
+
<div
|
|
44
|
+
className="rounded-lg border border-border bg-card"
|
|
45
|
+
role="table"
|
|
46
|
+
aria-label="Agent cost breakdown"
|
|
47
|
+
>
|
|
48
|
+
<div
|
|
49
|
+
role="row"
|
|
50
|
+
className="grid grid-cols-[1fr_auto_auto_auto] gap-x-4 border-b border-border px-3.5 py-2 text-[0.65rem] font-medium uppercase tracking-wider text-muted-foreground"
|
|
51
|
+
>
|
|
52
|
+
<span role="columnheader">Agent</span>
|
|
53
|
+
<span role="columnheader" className="text-right">
|
|
54
|
+
Runs
|
|
55
|
+
</span>
|
|
56
|
+
<span role="columnheader" className="text-right">
|
|
57
|
+
Tokens
|
|
58
|
+
</span>
|
|
59
|
+
<span role="columnheader" className="text-right">
|
|
60
|
+
Cost
|
|
61
|
+
</span>
|
|
62
|
+
</div>
|
|
63
|
+
{agents.map((agent) => {
|
|
64
|
+
const cost = Number(agent.billableCostMicros);
|
|
65
|
+
const pct = totalCost > 0 ? (cost / totalCost) * 100 : 0;
|
|
66
|
+
const barWidth =
|
|
67
|
+
maxCost > 0 ? (cost / maxCost) * 100 : 0;
|
|
68
|
+
|
|
69
|
+
const NameTag = agentHref ? "a" : "span";
|
|
70
|
+
const nameProps = agentHref
|
|
71
|
+
? { href: agentHref(agent.agentId) }
|
|
72
|
+
: {};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<div
|
|
76
|
+
key={agent.agentId}
|
|
77
|
+
className="border-b border-border-muted px-3.5 py-2 last:border-b-0"
|
|
78
|
+
>
|
|
79
|
+
<div
|
|
80
|
+
role="row"
|
|
81
|
+
className="grid grid-cols-[1fr_auto_auto_auto] gap-x-4"
|
|
82
|
+
>
|
|
83
|
+
<div role="cell" className="min-w-0">
|
|
84
|
+
<NameTag
|
|
85
|
+
{...nameProps}
|
|
86
|
+
className={cn(
|
|
87
|
+
"block truncate text-xs font-medium",
|
|
88
|
+
agentHref
|
|
89
|
+
? "text-primary hover:underline"
|
|
90
|
+
: "text-foreground",
|
|
91
|
+
)}
|
|
92
|
+
>
|
|
93
|
+
{agent.agentName || agent.agentId}
|
|
94
|
+
</NameTag>
|
|
95
|
+
</div>
|
|
96
|
+
<span
|
|
97
|
+
role="cell"
|
|
98
|
+
className="self-center text-right text-xs tabular-nums text-muted-foreground"
|
|
99
|
+
>
|
|
100
|
+
{agent.executionCount}
|
|
101
|
+
</span>
|
|
102
|
+
<span
|
|
103
|
+
role="cell"
|
|
104
|
+
className="self-center text-right text-xs tabular-nums text-muted-foreground"
|
|
105
|
+
>
|
|
106
|
+
{formatCompactTokens(Number(agent.totalTokens))}
|
|
107
|
+
</span>
|
|
108
|
+
<span
|
|
109
|
+
role="cell"
|
|
110
|
+
className="self-center text-right text-xs tabular-nums text-foreground"
|
|
111
|
+
>
|
|
112
|
+
{formatCost(cost / 1_000_000)}
|
|
113
|
+
<span className="ml-1.5 text-[0.6rem] text-muted-foreground">
|
|
114
|
+
{pct.toFixed(0)}%
|
|
115
|
+
</span>
|
|
116
|
+
</span>
|
|
117
|
+
</div>
|
|
118
|
+
{/* Proportional cost bar */}
|
|
119
|
+
<div className="mt-1.5 h-1 w-full rounded-full bg-muted">
|
|
120
|
+
<div
|
|
121
|
+
className="h-full rounded-full bg-chart-2 transition-all"
|
|
122
|
+
style={{ width: `${barWidth}%` }}
|
|
123
|
+
/>
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
);
|
|
127
|
+
})}
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function formatCompactTokens(n: number): string {
|
|
134
|
+
if (n >= 1_000_000) {
|
|
135
|
+
const v = n / 1_000_000;
|
|
136
|
+
return v >= 100 ? `${Math.round(v)}M` : `${trimZero(v.toFixed(1))}M`;
|
|
137
|
+
}
|
|
138
|
+
if (n >= 1_000) {
|
|
139
|
+
const v = n / 1_000;
|
|
140
|
+
return v >= 100 ? `${Math.round(v)}K` : `${trimZero(v.toFixed(1))}K`;
|
|
141
|
+
}
|
|
142
|
+
return String(n);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function trimZero(s: string): string {
|
|
146
|
+
return s.endsWith(".0") ? s.slice(0, -2) : s;
|
|
147
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stigmer/theme";
|
|
4
|
+
import { useBillingAccount } from "../billing/useBillingAccount";
|
|
5
|
+
import { useOrg } from "../organization/OrgProvider";
|
|
6
|
+
import { useDeploymentMode } from "../deployment-mode";
|
|
7
|
+
|
|
8
|
+
/** Props for {@link CreditRunwayIndicator}. */
|
|
9
|
+
export interface CreditRunwayIndicatorProps {
|
|
10
|
+
/** Total billable cost in micro-USD for the report period. */
|
|
11
|
+
readonly totalBillableCostMicros: bigint;
|
|
12
|
+
/** Number of calendar days the report covers. */
|
|
13
|
+
readonly daysInRange: number;
|
|
14
|
+
/** Additional CSS class names. */
|
|
15
|
+
readonly className?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Displays projected credit runway: "~N days at this rate".
|
|
20
|
+
*
|
|
21
|
+
* Computes runway by dividing available balance by the daily spend rate
|
|
22
|
+
* derived from the usage report. Color-coded by urgency:
|
|
23
|
+
* green (>14d), amber (7-14d), red (<7d).
|
|
24
|
+
*
|
|
25
|
+
* Requires `useBillingAccount` — renders nothing in local mode or if
|
|
26
|
+
* billing data is unavailable.
|
|
27
|
+
*/
|
|
28
|
+
export function CreditRunwayIndicator({
|
|
29
|
+
totalBillableCostMicros,
|
|
30
|
+
daysInRange,
|
|
31
|
+
className,
|
|
32
|
+
}: CreditRunwayIndicatorProps) {
|
|
33
|
+
const mode = useDeploymentMode();
|
|
34
|
+
const { activeOrg } = useOrg();
|
|
35
|
+
const orgId = activeOrg?.metadata?.id ?? "";
|
|
36
|
+
const { account } = useBillingAccount(mode === "cloud" ? orgId : "");
|
|
37
|
+
|
|
38
|
+
if (!account?.balance || daysInRange <= 0) return null;
|
|
39
|
+
|
|
40
|
+
const totalCost = Number(totalBillableCostMicros);
|
|
41
|
+
if (totalCost <= 0) return null;
|
|
42
|
+
|
|
43
|
+
const dailyRate = totalCost / daysInRange;
|
|
44
|
+
const availableMicros = Number(account.balance.availableMicros);
|
|
45
|
+
const runwayDays = Math.floor(availableMicros / dailyRate);
|
|
46
|
+
|
|
47
|
+
if (runwayDays < 0) return null;
|
|
48
|
+
|
|
49
|
+
const label =
|
|
50
|
+
runwayDays === 0
|
|
51
|
+
? "Less than 1 day remaining"
|
|
52
|
+
: `~${runwayDays} day${runwayDays === 1 ? "" : "s"} at this rate`;
|
|
53
|
+
|
|
54
|
+
const urgency: "healthy" | "warning" | "critical" =
|
|
55
|
+
runwayDays > 14 ? "healthy" : runwayDays >= 7 ? "warning" : "critical";
|
|
56
|
+
|
|
57
|
+
return (
|
|
58
|
+
<span
|
|
59
|
+
className={cn(
|
|
60
|
+
"text-xs tabular-nums",
|
|
61
|
+
urgency === "healthy" && "text-emerald-600 dark:text-emerald-400",
|
|
62
|
+
urgency === "warning" && "text-amber-600 dark:text-amber-400",
|
|
63
|
+
urgency === "critical" && "text-red-600 dark:text-red-400",
|
|
64
|
+
className,
|
|
65
|
+
)}
|
|
66
|
+
aria-label={`Credit runway: ${label}`}
|
|
67
|
+
>
|
|
68
|
+
{label}
|
|
69
|
+
</span>
|
|
70
|
+
);
|
|
71
|
+
}
|