@stigmer/react 3.2.2 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/agent/AgentDetailView.d.ts.map +1 -1
- package/agent/AgentDetailView.js +6 -3
- package/agent/AgentDetailView.js.map +1 -1
- package/agent/steps/ReviewStep.d.ts.map +1 -1
- package/agent/steps/ReviewStep.js +2 -3
- package/agent/steps/ReviewStep.js.map +1 -1
- package/billing/BaselineEditor.d.ts +9 -0
- package/billing/BaselineEditor.d.ts.map +1 -0
- package/billing/BaselineEditor.js +253 -0
- package/billing/BaselineEditor.js.map +1 -0
- package/billing/ModelCatalogPanel.d.ts +28 -0
- package/billing/ModelCatalogPanel.d.ts.map +1 -0
- package/billing/ModelCatalogPanel.js +102 -0
- package/billing/ModelCatalogPanel.js.map +1 -0
- package/billing/ModelGovernanceDetail.d.ts +8 -0
- package/billing/ModelGovernanceDetail.d.ts.map +1 -0
- package/billing/ModelGovernanceDetail.js +64 -0
- package/billing/ModelGovernanceDetail.js.map +1 -0
- package/billing/OperatorAccessNotice.d.ts +12 -0
- package/billing/OperatorAccessNotice.d.ts.map +1 -0
- package/billing/OperatorAccessNotice.js +15 -0
- package/billing/OperatorAccessNotice.js.map +1 -0
- package/billing/PricingGovernanceConsole.d.ts +57 -0
- package/billing/PricingGovernanceConsole.d.ts.map +1 -0
- package/billing/PricingGovernanceConsole.js +164 -0
- package/billing/PricingGovernanceConsole.js.map +1 -0
- package/billing/PricingGovernancePanel.d.ts +26 -0
- package/billing/PricingGovernancePanel.d.ts.map +1 -0
- package/billing/PricingGovernancePanel.js +64 -0
- package/billing/PricingGovernancePanel.js.map +1 -0
- package/billing/RetireConfirm.d.ts +9 -0
- package/billing/RetireConfirm.d.ts.map +1 -0
- package/billing/RetireConfirm.js +19 -0
- package/billing/RetireConfirm.js.map +1 -0
- package/billing/form-primitives.d.ts +18 -0
- package/billing/form-primitives.d.ts.map +1 -0
- package/billing/form-primitives.js +19 -0
- package/billing/form-primitives.js.map +1 -0
- package/billing/governance-primitives.d.ts +33 -0
- package/billing/governance-primitives.d.ts.map +1 -0
- package/billing/governance-primitives.js +43 -0
- package/billing/governance-primitives.js.map +1 -0
- package/billing/index.d.ts +18 -0
- package/billing/index.d.ts.map +1 -1
- package/billing/index.js +9 -0
- package/billing/index.js.map +1 -1
- package/billing/pricing-format.d.ts +12 -0
- package/billing/pricing-format.d.ts.map +1 -0
- package/billing/pricing-format.js +50 -0
- package/billing/pricing-format.js.map +1 -0
- package/billing/useDecidePricingOverride.d.ts +46 -0
- package/billing/useDecidePricingOverride.d.ts.map +1 -0
- package/billing/useDecidePricingOverride.js +44 -0
- package/billing/useDecidePricingOverride.js.map +1 -0
- package/billing/useModelGovernanceView.d.ts +103 -0
- package/billing/useModelGovernanceView.d.ts.map +1 -0
- package/billing/useModelGovernanceView.js +144 -0
- package/billing/useModelGovernanceView.js.map +1 -0
- package/billing/useModelPricingBaselines.d.ts +40 -0
- package/billing/useModelPricingBaselines.d.ts.map +1 -0
- package/billing/useModelPricingBaselines.js +32 -0
- package/billing/useModelPricingBaselines.js.map +1 -0
- package/billing/usePricingGovernance.d.ts +39 -0
- package/billing/usePricingGovernance.d.ts.map +1 -0
- package/billing/usePricingGovernance.js +31 -0
- package/billing/usePricingGovernance.js.map +1 -0
- package/billing/useRetireModelPricingBaseline.d.ts +31 -0
- package/billing/useRetireModelPricingBaseline.d.ts.map +1 -0
- package/billing/useRetireModelPricingBaseline.js +36 -0
- package/billing/useRetireModelPricingBaseline.js.map +1 -0
- package/billing/useUpsertModelPricingBaseline.d.ts +38 -0
- package/billing/useUpsertModelPricingBaseline.d.ts.map +1 -0
- package/billing/useUpsertModelPricingBaseline.js +37 -0
- package/billing/useUpsertModelPricingBaseline.js.map +1 -0
- package/channel/AgentChannelsPanel.d.ts.map +1 -1
- package/channel/AgentChannelsPanel.js +11 -5
- package/channel/AgentChannelsPanel.js.map +1 -1
- package/composer/SessionComposer.d.ts +1 -1
- package/cursor-accounts/CursorAccountEditor.d.ts +28 -0
- package/cursor-accounts/CursorAccountEditor.d.ts.map +1 -0
- package/cursor-accounts/CursorAccountEditor.js +51 -0
- package/cursor-accounts/CursorAccountEditor.js.map +1 -0
- package/cursor-accounts/CursorAccountsAccessNotice.d.ts +11 -0
- package/cursor-accounts/CursorAccountsAccessNotice.d.ts.map +1 -0
- package/cursor-accounts/CursorAccountsAccessNotice.js +14 -0
- package/cursor-accounts/CursorAccountsAccessNotice.js.map +1 -0
- package/cursor-accounts/CursorAccountsConsole.d.ts +28 -0
- package/cursor-accounts/CursorAccountsConsole.d.ts.map +1 -0
- package/cursor-accounts/CursorAccountsConsole.js +275 -0
- package/cursor-accounts/CursorAccountsConsole.js.map +1 -0
- package/cursor-accounts/cursor-account-format.d.ts +10 -0
- package/cursor-accounts/cursor-account-format.d.ts.map +1 -0
- package/cursor-accounts/cursor-account-format.js +26 -0
- package/cursor-accounts/cursor-account-format.js.map +1 -0
- package/cursor-accounts/index.d.ts +18 -0
- package/cursor-accounts/index.d.ts.map +1 -0
- package/cursor-accounts/index.js +13 -0
- package/cursor-accounts/index.js.map +1 -0
- package/cursor-accounts/useCursorAccountView.d.ts +30 -0
- package/cursor-accounts/useCursorAccountView.d.ts.map +1 -0
- package/cursor-accounts/useCursorAccountView.js +25 -0
- package/cursor-accounts/useCursorAccountView.js.map +1 -0
- package/cursor-accounts/useCursorAccounts.d.ts +33 -0
- package/cursor-accounts/useCursorAccounts.d.ts.map +1 -0
- package/cursor-accounts/useCursorAccounts.js +25 -0
- package/cursor-accounts/useCursorAccounts.js.map +1 -0
- package/cursor-accounts/useCursorMemberKeyActions.d.ts +49 -0
- package/cursor-accounts/useCursorMemberKeyActions.d.ts.map +1 -0
- package/cursor-accounts/useCursorMemberKeyActions.js +38 -0
- package/cursor-accounts/useCursorMemberKeyActions.js.map +1 -0
- package/cursor-accounts/useDeleteCursorAccount.d.ts +30 -0
- package/cursor-accounts/useDeleteCursorAccount.d.ts.map +1 -0
- package/cursor-accounts/useDeleteCursorAccount.js +32 -0
- package/cursor-accounts/useDeleteCursorAccount.js.map +1 -0
- package/cursor-accounts/useSyncCursorAccount.d.ts +23 -0
- package/cursor-accounts/useSyncCursorAccount.d.ts.map +1 -0
- package/cursor-accounts/useSyncCursorAccount.js +31 -0
- package/cursor-accounts/useSyncCursorAccount.js.map +1 -0
- package/cursor-accounts/useUpsertCursorAccount.d.ts +26 -0
- package/cursor-accounts/useUpsertCursorAccount.d.ts.map +1 -0
- package/cursor-accounts/useUpsertCursorAccount.js +34 -0
- package/cursor-accounts/useUpsertCursorAccount.js.map +1 -0
- package/datastore/CollectionRecordsBrowser.d.ts +34 -0
- package/datastore/CollectionRecordsBrowser.d.ts.map +1 -0
- package/datastore/CollectionRecordsBrowser.js +209 -0
- package/datastore/CollectionRecordsBrowser.js.map +1 -0
- package/datastore/CollectionSchemaView.d.ts +29 -0
- package/datastore/CollectionSchemaView.d.ts.map +1 -0
- package/datastore/CollectionSchemaView.js +93 -0
- package/datastore/CollectionSchemaView.js.map +1 -0
- package/datastore/DatastoreDetailView.d.ts +44 -0
- package/datastore/DatastoreDetailView.d.ts.map +1 -0
- package/datastore/DatastoreDetailView.js +76 -0
- package/datastore/DatastoreDetailView.js.map +1 -0
- package/datastore/DatastoreSyncReport.d.ts +19 -0
- package/datastore/DatastoreSyncReport.d.ts.map +1 -0
- package/datastore/DatastoreSyncReport.js +45 -0
- package/datastore/DatastoreSyncReport.js.map +1 -0
- package/datastore/DeleteDatastoreDialog.d.ts +35 -0
- package/datastore/DeleteDatastoreDialog.d.ts.map +1 -0
- package/datastore/DeleteDatastoreDialog.js +90 -0
- package/datastore/DeleteDatastoreDialog.js.map +1 -0
- package/datastore/FieldValueControl.d.ts +55 -0
- package/datastore/FieldValueControl.d.ts.map +1 -0
- package/datastore/FieldValueControl.js +138 -0
- package/datastore/FieldValueControl.js.map +1 -0
- package/datastore/RecordFilterBuilder.d.ts +30 -0
- package/datastore/RecordFilterBuilder.d.ts.map +1 -0
- package/datastore/RecordFilterBuilder.js +122 -0
- package/datastore/RecordFilterBuilder.js.map +1 -0
- package/datastore/RecordFormPanel.d.ts +45 -0
- package/datastore/RecordFormPanel.d.ts.map +1 -0
- package/datastore/RecordFormPanel.js +215 -0
- package/datastore/RecordFormPanel.js.map +1 -0
- package/datastore/index.d.ts +43 -0
- package/datastore/index.d.ts.map +1 -0
- package/datastore/index.js +22 -0
- package/datastore/index.js.map +1 -0
- package/datastore/recordFilter.d.ts +54 -0
- package/datastore/recordFilter.d.ts.map +1 -0
- package/datastore/recordFilter.js +93 -0
- package/datastore/recordFilter.js.map +1 -0
- package/datastore/recordValues.d.ts +85 -0
- package/datastore/recordValues.d.ts.map +1 -0
- package/datastore/recordValues.js +282 -0
- package/datastore/recordValues.js.map +1 -0
- package/datastore/useDatastore.d.ts +39 -0
- package/datastore/useDatastore.d.ts.map +1 -0
- package/datastore/useDatastore.js +44 -0
- package/datastore/useDatastore.js.map +1 -0
- package/datastore/useDatastoreCount.d.ts +48 -0
- package/datastore/useDatastoreCount.d.ts.map +1 -0
- package/datastore/useDatastoreCount.js +27 -0
- package/datastore/useDatastoreCount.js.map +1 -0
- package/datastore/useDatastoreDescription.d.ts +54 -0
- package/datastore/useDatastoreDescription.d.ts.map +1 -0
- package/datastore/useDatastoreDescription.js +50 -0
- package/datastore/useDatastoreDescription.js.map +1 -0
- package/datastore/useDatastoreList.d.ts +57 -0
- package/datastore/useDatastoreList.d.ts.map +1 -0
- package/datastore/useDatastoreList.js +29 -0
- package/datastore/useDatastoreList.js.map +1 -0
- package/datastore/useDatastoreSearch.d.ts +19 -0
- package/datastore/useDatastoreSearch.d.ts.map +1 -0
- package/datastore/useDatastoreSearch.js +22 -0
- package/datastore/useDatastoreSearch.js.map +1 -0
- package/datastore/useDeleteDatastore.d.ts +53 -0
- package/datastore/useDeleteDatastore.d.ts.map +1 -0
- package/datastore/useDeleteDatastore.js +40 -0
- package/datastore/useDeleteDatastore.js.map +1 -0
- package/datastore/useDeleteRecord.d.ts +34 -0
- package/datastore/useDeleteRecord.d.ts.map +1 -0
- package/datastore/useDeleteRecord.js +43 -0
- package/datastore/useDeleteRecord.js.map +1 -0
- package/datastore/useInsertRecord.d.ts +50 -0
- package/datastore/useInsertRecord.d.ts.map +1 -0
- package/datastore/useInsertRecord.js +55 -0
- package/datastore/useInsertRecord.js.map +1 -0
- package/datastore/useRecordCollection.d.ts +104 -0
- package/datastore/useRecordCollection.d.ts.map +1 -0
- package/datastore/useRecordCollection.js +136 -0
- package/datastore/useRecordCollection.js.map +1 -0
- package/datastore/useRecordList.d.ts +66 -0
- package/datastore/useRecordList.d.ts.map +1 -0
- package/datastore/useRecordList.js +58 -0
- package/datastore/useRecordList.js.map +1 -0
- package/datastore/useUpdateRecord.d.ts +52 -0
- package/datastore/useUpdateRecord.d.ts.map +1 -0
- package/datastore/useUpdateRecord.js +55 -0
- package/datastore/useUpdateRecord.js.map +1 -0
- package/environment/EnvironmentListPanel.d.ts.map +1 -1
- package/environment/EnvironmentListPanel.js +12 -7
- package/environment/EnvironmentListPanel.js.map +1 -1
- package/execution/index.d.ts +1 -2
- package/execution/index.d.ts.map +1 -1
- package/execution/index.js +0 -1
- package/execution/index.js.map +1 -1
- package/execution/useLiveAgentExecution.d.ts +17 -1
- package/execution/useLiveAgentExecution.d.ts.map +1 -1
- package/execution/useLiveAgentExecution.js +19 -4
- package/execution/useLiveAgentExecution.js.map +1 -1
- package/iam-policy/index.d.ts +1 -1
- package/iam-policy/index.d.ts.map +1 -1
- package/iam-policy/index.js.map +1 -1
- package/iam-policy/useCheckPermission.d.ts +32 -11
- package/iam-policy/useCheckPermission.d.ts.map +1 -1
- package/iam-policy/useCheckPermission.js +24 -19
- package/iam-policy/useCheckPermission.js.map +1 -1
- package/index.d.ts +16 -10
- package/index.d.ts.map +1 -1
- package/index.js +16 -5
- package/index.js.map +1 -1
- package/internal/useInViewport.d.ts +24 -0
- package/internal/useInViewport.d.ts.map +1 -0
- package/internal/useInViewport.js +49 -0
- package/internal/useInViewport.js.map +1 -0
- package/library/VisibilitySelector.d.ts +22 -6
- package/library/VisibilitySelector.d.ts.map +1 -1
- package/library/VisibilitySelector.js +12 -4
- package/library/VisibilitySelector.js.map +1 -1
- package/library/index.d.ts +1 -8
- package/library/index.d.ts.map +1 -1
- package/library/index.js +0 -4
- package/library/index.js.map +1 -1
- package/library/useApplyResource.d.ts +12 -12
- package/library/useApplyResource.d.ts.map +1 -1
- package/library/useApplyResource.js +16 -25
- package/library/useApplyResource.js.map +1 -1
- package/library/useExportResource.d.ts +13 -9
- package/library/useExportResource.d.ts.map +1 -1
- package/library/useExportResource.js +18 -36
- package/library/useExportResource.js.map +1 -1
- package/manifest/ApplyManifestDialog.d.ts +48 -0
- package/manifest/ApplyManifestDialog.d.ts.map +1 -0
- package/manifest/ApplyManifestDialog.js +135 -0
- package/manifest/ApplyManifestDialog.js.map +1 -0
- package/manifest/EditResourceYamlDialog.d.ts +51 -0
- package/manifest/EditResourceYamlDialog.d.ts.map +1 -0
- package/manifest/EditResourceYamlDialog.js +104 -0
- package/manifest/EditResourceYamlDialog.js.map +1 -0
- package/manifest/RedactedSecretsNotice.d.ts +14 -0
- package/manifest/RedactedSecretsNotice.d.ts.map +1 -0
- package/manifest/RedactedSecretsNotice.js +14 -0
- package/manifest/RedactedSecretsNotice.js.map +1 -0
- package/manifest/YamlEditor.d.ts +44 -0
- package/manifest/YamlEditor.d.ts.map +1 -0
- package/manifest/YamlEditor.js +216 -0
- package/manifest/YamlEditor.js.map +1 -0
- package/manifest/index.d.ts +13 -0
- package/manifest/index.d.ts.map +1 -0
- package/manifest/index.js +13 -0
- package/manifest/index.js.map +1 -0
- package/manifest/useApplyManifest.d.ts +82 -0
- package/manifest/useApplyManifest.d.ts.map +1 -0
- package/manifest/useApplyManifest.js +180 -0
- package/manifest/useApplyManifest.js.map +1 -0
- package/manifest/useEditResourceYaml.d.ts +106 -0
- package/manifest/useEditResourceYaml.d.ts.map +1 -0
- package/manifest/useEditResourceYaml.js +168 -0
- package/manifest/useEditResourceYaml.js.map +1 -0
- package/mcp-server/McpServerDetailView.d.ts.map +1 -1
- package/mcp-server/McpServerDetailView.js +4 -3
- package/mcp-server/McpServerDetailView.js.map +1 -1
- package/mcp-server/steps/ReviewStep.d.ts.map +1 -1
- package/mcp-server/steps/ReviewStep.js +2 -3
- package/mcp-server/steps/ReviewStep.js.map +1 -1
- package/package.json +4 -4
- package/resource-creation/templates/workflow-templates.js +4 -4
- package/session/SessionViewer.js +8 -1
- package/session/SessionViewer.js.map +1 -1
- package/session/audience.d.ts +6 -1
- package/session/audience.d.ts.map +1 -1
- package/session/useEditSessionPrep.js +3 -3
- package/session/useEditSessionPrep.js.map +1 -1
- package/settings/index.d.ts +2 -1
- package/settings/index.d.ts.map +1 -1
- package/settings/index.js +2 -1
- package/settings/index.js.map +1 -1
- package/settings/settings-nav.d.ts +22 -0
- package/settings/settings-nav.d.ts.map +1 -1
- package/settings/settings-nav.js +32 -1
- package/settings/settings-nav.js.map +1 -1
- package/settings/useSettingsNavGroups.d.ts +29 -0
- package/settings/useSettingsNavGroups.d.ts.map +1 -0
- package/settings/useSettingsNavGroups.js +61 -0
- package/settings/useSettingsNavGroups.js.map +1 -0
- package/skill/SkillDetailView.d.ts.map +1 -1
- package/skill/SkillDetailView.js +4 -3
- package/skill/SkillDetailView.js.map +1 -1
- package/src/access/__tests__/useManageAccess.test.tsx +104 -0
- package/src/agent/AgentDetailView.tsx +9 -3
- package/src/agent/steps/ReviewStep.tsx +2 -3
- package/src/billing/BaselineEditor.tsx +619 -0
- package/src/billing/ModelCatalogPanel.tsx +283 -0
- package/src/billing/ModelGovernanceDetail.tsx +289 -0
- package/src/billing/OperatorAccessNotice.tsx +32 -0
- package/src/billing/PricingGovernanceConsole.tsx +465 -0
- package/src/billing/PricingGovernancePanel.tsx +166 -0
- package/src/billing/RetireConfirm.tsx +82 -0
- package/src/billing/__tests__/ModelCatalogPanel.test.tsx +253 -0
- package/src/billing/__tests__/PricingGovernanceConsole.test.tsx +410 -0
- package/src/billing/__tests__/useModelGovernanceView.test.tsx +308 -0
- package/src/billing/form-primitives.tsx +68 -0
- package/src/billing/governance-primitives.tsx +133 -0
- package/src/billing/index.ts +37 -0
- package/src/billing/pricing-format.ts +53 -0
- package/src/billing/useDecidePricingOverride.ts +78 -0
- package/src/billing/useModelGovernanceView.ts +290 -0
- package/src/billing/useModelPricingBaselines.ts +69 -0
- package/src/billing/usePricingGovernance.ts +57 -0
- package/src/billing/useRetireModelPricingBaseline.ts +65 -0
- package/src/billing/useUpsertModelPricingBaseline.ts +72 -0
- package/src/channel/AgentChannelsPanel.tsx +27 -1
- package/src/composer/SessionComposer.tsx +1 -1
- package/src/cursor-accounts/CursorAccountEditor.tsx +181 -0
- package/src/cursor-accounts/CursorAccountsAccessNotice.tsx +36 -0
- package/src/cursor-accounts/CursorAccountsConsole.tsx +810 -0
- package/src/cursor-accounts/__tests__/CursorAccountsConsole.test.tsx +384 -0
- package/src/cursor-accounts/cursor-account-format.ts +29 -0
- package/src/cursor-accounts/index.ts +29 -0
- package/src/cursor-accounts/useCursorAccountView.ts +49 -0
- package/src/cursor-accounts/useCursorAccounts.ts +49 -0
- package/src/cursor-accounts/useCursorMemberKeyActions.ts +106 -0
- package/src/cursor-accounts/useDeleteCursorAccount.ts +62 -0
- package/src/cursor-accounts/useSyncCursorAccount.ts +54 -0
- package/src/cursor-accounts/useUpsertCursorAccount.ts +57 -0
- package/src/datastore/CollectionRecordsBrowser.tsx +544 -0
- package/src/datastore/CollectionSchemaView.tsx +247 -0
- package/src/datastore/DatastoreDetailView.tsx +201 -0
- package/src/datastore/DatastoreSyncReport.tsx +105 -0
- package/src/datastore/DeleteDatastoreDialog.tsx +202 -0
- package/src/datastore/FieldValueControl.tsx +289 -0
- package/src/datastore/RecordFilterBuilder.tsx +411 -0
- package/src/datastore/RecordFormPanel.tsx +432 -0
- package/src/datastore/__tests__/CollectionRecordsBrowser.test.tsx +207 -0
- package/src/datastore/__tests__/DeleteDatastoreDialog.test.tsx +133 -0
- package/src/datastore/__tests__/FieldValueControl.test.tsx +160 -0
- package/src/datastore/__tests__/RecordFilterBuilder.test.tsx +141 -0
- package/src/datastore/__tests__/RecordFormPanel.test.tsx +227 -0
- package/src/datastore/__tests__/recordFilter.test.ts +156 -0
- package/src/datastore/__tests__/recordMutations.test.tsx +195 -0
- package/src/datastore/__tests__/recordValues.test.ts +359 -0
- package/src/datastore/__tests__/schemaAndSyncViews.test.tsx +142 -0
- package/src/datastore/__tests__/useDatastoreDescription.test.tsx +143 -0
- package/src/datastore/__tests__/useRecordCollection.test.tsx +250 -0
- package/src/datastore/__tests__/useRecordList.test.tsx +85 -0
- package/src/datastore/index.ts +111 -0
- package/src/datastore/recordFilter.ts +140 -0
- package/src/datastore/recordValues.ts +327 -0
- package/src/datastore/useDatastore.ts +67 -0
- package/src/datastore/useDatastoreCount.ts +67 -0
- package/src/datastore/useDatastoreDescription.ts +90 -0
- package/src/datastore/useDatastoreList.ts +79 -0
- package/src/datastore/useDatastoreSearch.ts +39 -0
- package/src/datastore/useDeleteDatastore.ts +87 -0
- package/src/datastore/useDeleteRecord.ts +77 -0
- package/src/datastore/useInsertRecord.ts +92 -0
- package/src/datastore/useRecordCollection.ts +256 -0
- package/src/datastore/useRecordList.ts +131 -0
- package/src/datastore/useUpdateRecord.ts +95 -0
- package/src/environment/EnvironmentListPanel.tsx +24 -0
- package/src/execution/__tests__/useArtifactInspection.test.tsx +12 -2
- package/src/execution/__tests__/useLiveAgentExecution.test.tsx +125 -0
- package/src/execution/index.ts +4 -7
- package/src/execution/useLiveAgentExecution.ts +41 -3
- package/src/iam-policy/__tests__/useCheckPermission.test.tsx +221 -0
- package/src/iam-policy/index.ts +1 -0
- package/src/iam-policy/useCheckPermission.ts +45 -19
- package/src/index.ts +167 -18
- package/src/internal/__tests__/useInViewport.test.tsx +115 -0
- package/src/internal/useInViewport.ts +63 -0
- package/src/library/VisibilitySelector.tsx +50 -9
- package/src/library/__tests__/VisibilitySelector.test.tsx +38 -0
- package/src/library/index.ts +4 -21
- package/src/library/useApplyResource.ts +27 -34
- package/src/library/useExportResource.ts +21 -40
- package/src/manifest/ApplyManifestDialog.tsx +315 -0
- package/src/manifest/EditResourceYamlDialog.tsx +265 -0
- package/src/manifest/RedactedSecretsNotice.tsx +30 -0
- package/src/manifest/YamlEditor.tsx +272 -0
- package/src/manifest/__tests__/EditResourceYamlDialog.test.tsx +118 -0
- package/src/manifest/__tests__/useApplyManifest.test.tsx +237 -0
- package/src/manifest/__tests__/useEditResourceYaml.test.tsx +252 -0
- package/src/manifest/index.ts +33 -0
- package/src/manifest/useApplyManifest.ts +270 -0
- package/src/manifest/useEditResourceYaml.ts +273 -0
- package/src/mcp-server/McpServerDetailView.tsx +7 -3
- package/src/mcp-server/steps/ReviewStep.tsx +2 -3
- package/src/resource-creation/templates/workflow-templates.ts +4 -4
- package/src/session/SessionViewer.tsx +7 -1
- package/src/session/__tests__/audienceWiring.test.tsx +31 -1
- package/src/session/audience.ts +6 -1
- package/src/session/useEditSessionPrep.ts +3 -3
- package/src/settings/__tests__/useSettingsNavGroups.test.tsx +138 -0
- package/src/settings/index.ts +5 -1
- package/src/settings/settings-nav.ts +43 -0
- package/src/settings/useSettingsNavGroups.ts +81 -0
- package/src/skill/SkillDetailView.tsx +7 -3
- package/src/workflow/WorkflowAgentCallTranscript.tsx +279 -0
- package/src/workflow/WorkflowDetailView.tsx +7 -3
- package/src/workflow/WorkflowExecutionViewer.tsx +20 -77
- package/src/workflow/WorkflowTaskApprovalSummary.tsx +45 -8
- package/src/workflow/WorkflowYamlEditor.tsx +6 -270
- package/src/workflow/__tests__/WorkflowAgentCallTranscript.liveregion.test.tsx +124 -0
- package/src/workflow/__tests__/{WorkflowAgentExecutionDocument.test.tsx → WorkflowAgentCallTranscript.test.tsx} +146 -121
- package/src/workflow/__tests__/WorkflowExecutionViewer.approvals.test.tsx +81 -220
- package/src/workflow/__tests__/WorkflowExecutionViewer.reconciliation.test.tsx +17 -16
- package/src/workflow/__tests__/WorkflowTaskApprovalSummary.test.tsx +52 -2
- package/src/workflow/__tests__/WorkflowTaskThread.test.tsx +168 -185
- package/src/workflow/__tests__/agent-call-live-experience.test.ts +4 -4
- package/src/workflow/__tests__/task-approval.test.ts +119 -0
- package/src/workflow/__tests__/task-presentation.test.ts +35 -1
- package/src/workflow/__tests__/useWorkflowExecutionPanel.test.ts +0 -57
- package/src/workflow/index.ts +6 -3
- package/src/workflow/task-detail/index.ts +3 -0
- package/src/workflow/task-detail/task-approval.ts +95 -1
- package/src/workflow/thread/WorkflowTaskThread.tsx +96 -252
- package/src/workflow/thread/task-presentation.ts +8 -2
- package/src/workflow/useWorkflowExecutionPanel.ts +0 -47
- package/styles.css +1 -1
- package/workflow/CanvasTransitionEdge.d.ts +1 -1
- package/workflow/WorkflowAgentCallTranscript.d.ts +87 -0
- package/workflow/WorkflowAgentCallTranscript.d.ts.map +1 -0
- package/workflow/WorkflowAgentCallTranscript.js +98 -0
- package/workflow/WorkflowAgentCallTranscript.js.map +1 -0
- package/workflow/WorkflowDetailView.d.ts.map +1 -1
- package/workflow/WorkflowDetailView.js +4 -3
- package/workflow/WorkflowDetailView.js.map +1 -1
- package/workflow/WorkflowExecutionViewer.d.ts.map +1 -1
- package/workflow/WorkflowExecutionViewer.js +23 -52
- package/workflow/WorkflowExecutionViewer.js.map +1 -1
- package/workflow/WorkflowTaskApprovalSummary.d.ts +1 -1
- package/workflow/WorkflowTaskApprovalSummary.d.ts.map +1 -1
- package/workflow/WorkflowTaskApprovalSummary.js +18 -1
- package/workflow/WorkflowTaskApprovalSummary.js.map +1 -1
- package/workflow/WorkflowYamlEditor.d.ts +2 -42
- package/workflow/WorkflowYamlEditor.d.ts.map +1 -1
- package/workflow/WorkflowYamlEditor.js +5 -214
- package/workflow/WorkflowYamlEditor.js.map +1 -1
- package/workflow/index.d.ts +2 -2
- package/workflow/index.d.ts.map +1 -1
- package/workflow/index.js +2 -2
- package/workflow/index.js.map +1 -1
- package/workflow/task-detail/index.d.ts +1 -1
- package/workflow/task-detail/index.d.ts.map +1 -1
- package/workflow/task-detail/index.js +1 -1
- package/workflow/task-detail/index.js.map +1 -1
- package/workflow/task-detail/task-approval.d.ts +44 -1
- package/workflow/task-detail/task-approval.d.ts.map +1 -1
- package/workflow/task-detail/task-approval.js +47 -0
- package/workflow/task-detail/task-approval.js.map +1 -1
- package/workflow/thread/WorkflowTaskThread.d.ts +17 -25
- package/workflow/thread/WorkflowTaskThread.d.ts.map +1 -1
- package/workflow/thread/WorkflowTaskThread.js +60 -105
- package/workflow/thread/WorkflowTaskThread.js.map +1 -1
- package/workflow/thread/task-presentation.d.ts.map +1 -1
- package/workflow/thread/task-presentation.js +7 -2
- package/workflow/thread/task-presentation.js.map +1 -1
- package/workflow/useWorkflowExecutionPanel.d.ts +0 -12
- package/workflow/useWorkflowExecutionPanel.d.ts.map +1 -1
- package/workflow/useWorkflowExecutionPanel.js +0 -12
- package/workflow/useWorkflowExecutionPanel.js.map +1 -1
- package/execution/agent-execution-document.d.ts +0 -31
- package/execution/agent-execution-document.d.ts.map +0 -1
- package/execution/agent-execution-document.js +0 -48
- package/execution/agent-execution-document.js.map +0 -1
- package/library/ImportResourceDialog.d.ts +0 -43
- package/library/ImportResourceDialog.d.ts.map +0 -1
- package/library/ImportResourceDialog.js +0 -90
- package/library/ImportResourceDialog.js.map +0 -1
- package/library/parse-resource-yaml.d.ts +0 -63
- package/library/parse-resource-yaml.d.ts.map +0 -1
- package/library/parse-resource-yaml.js +0 -407
- package/library/parse-resource-yaml.js.map +0 -1
- package/library/serialize-resource-yaml.d.ts +0 -103
- package/library/serialize-resource-yaml.d.ts.map +0 -1
- package/library/serialize-resource-yaml.js +0 -565
- package/library/serialize-resource-yaml.js.map +0 -1
- package/library/useImportResource.d.ts +0 -84
- package/library/useImportResource.d.ts.map +0 -1
- package/library/useImportResource.js +0 -188
- package/library/useImportResource.js.map +0 -1
- package/src/execution/__tests__/agent-execution-document.test.ts +0 -45
- package/src/execution/agent-execution-document.ts +0 -54
- package/src/library/ImportResourceDialog.tsx +0 -227
- package/src/library/parse-resource-yaml.ts +0 -630
- package/src/library/serialize-resource-yaml.ts +0 -756
- package/src/library/useImportResource.ts +0 -253
- package/src/workflow/WorkflowAgentExecutionDocument.tsx +0 -283
- package/workflow/WorkflowAgentExecutionDocument.d.ts +0 -79
- package/workflow/WorkflowAgentExecutionDocument.d.ts.map +0 -1
- package/workflow/WorkflowAgentExecutionDocument.js +0 -87
- package/workflow/WorkflowAgentExecutionDocument.js.map +0 -1
|
@@ -0,0 +1,465 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useState } from "react";
|
|
4
|
+
import { cn } from "@stigmer/theme";
|
|
5
|
+
import { getUserMessage, isPermissionDenied } from "@stigmer/sdk";
|
|
6
|
+
import type { ModelPricingBaseline } from "@stigmer/protos/ai/stigmer/billing/v1/model_pricing_baseline_pb";
|
|
7
|
+
import { Button } from "../button/index.js";
|
|
8
|
+
import { Tabs } from "../tabs/Tabs.js";
|
|
9
|
+
import { BaselineEditor } from "./BaselineEditor.js";
|
|
10
|
+
import { RetireConfirm } from "./RetireConfirm.js";
|
|
11
|
+
import { ModelGovernanceDetail } from "./ModelGovernanceDetail.js";
|
|
12
|
+
import { OperatorAccessNotice } from "./OperatorAccessNotice.js";
|
|
13
|
+
import { GovernanceBadge, PendingOverrideCard, RateCell } from "./governance-primitives.js";
|
|
14
|
+
import { INPUT_CLASSES } from "./form-primitives.js";
|
|
15
|
+
import { ZERO } from "./pricing-format.js";
|
|
16
|
+
import { useDecidePricingOverride } from "./useDecidePricingOverride.js";
|
|
17
|
+
import { useRetireModelPricingBaseline } from "./useRetireModelPricingBaseline.js";
|
|
18
|
+
import { useUpsertModelPricingBaseline } from "./useUpsertModelPricingBaseline.js";
|
|
19
|
+
import {
|
|
20
|
+
useModelGovernanceView,
|
|
21
|
+
type ModelGovernanceRow,
|
|
22
|
+
} from "./useModelGovernanceView.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Tab ids of {@link PricingGovernanceConsole}, accepted by
|
|
26
|
+
* {@link PricingGovernanceConsoleProps.defaultTab}.
|
|
27
|
+
*
|
|
28
|
+
* These ids are deep-link targets: consumers wire them from their own
|
|
29
|
+
* routing (e.g. a `?tab=sign-offs` query param), and external surfaces
|
|
30
|
+
* compose URLs against them. Renaming a member is a breaking change to
|
|
31
|
+
* every link in the wild, not just to this component's props.
|
|
32
|
+
*/
|
|
33
|
+
export type PricingGovernanceTab = "models" | "sign-offs";
|
|
34
|
+
|
|
35
|
+
/** Props for {@link PricingGovernanceConsole}. */
|
|
36
|
+
export interface PricingGovernanceConsoleProps {
|
|
37
|
+
/** Additional CSS class names. */
|
|
38
|
+
readonly className?: string;
|
|
39
|
+
/**
|
|
40
|
+
* The tab shown on first render. Defaults to `"models"`.
|
|
41
|
+
*
|
|
42
|
+
* Read once at mount, like a form field's `defaultValue` — changing
|
|
43
|
+
* it afterwards has no effect, and the user's tab choice stays local
|
|
44
|
+
* (the console never writes it back anywhere). Wire it from routing
|
|
45
|
+
* to make the tab URL-addressable:
|
|
46
|
+
*
|
|
47
|
+
* ```tsx
|
|
48
|
+
* // e.g. honoring a ?tab=sign-offs deep link
|
|
49
|
+
* const tab = new URLSearchParams(window.location.search).get("tab");
|
|
50
|
+
* <PricingGovernanceConsole
|
|
51
|
+
* defaultTab={tab === "sign-offs" ? "sign-offs" : undefined}
|
|
52
|
+
* />
|
|
53
|
+
* ```
|
|
54
|
+
*/
|
|
55
|
+
readonly defaultTab?: PricingGovernanceTab;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const TABS: readonly { readonly id: PricingGovernanceTab; readonly label: string }[] = [
|
|
59
|
+
{ id: "models", label: "Models" },
|
|
60
|
+
{ id: "sign-offs", label: "Sign-Offs" },
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The platform-operator pricing console: a tabbed surface over the
|
|
65
|
+
* model registry baseline and the pricing feedback loop.
|
|
66
|
+
*
|
|
67
|
+
* - **Models** — every catalog entry joined with its governance state
|
|
68
|
+
* (effective vs baseline rates, ledger verification), searchable.
|
|
69
|
+
* Selecting a row opens a read-only detail record; editing (with an
|
|
70
|
+
* explicit old→new rate confirmation) and typed-confirmation
|
|
71
|
+
* retirement are deliberate steps from there.
|
|
72
|
+
* - **Sign-Offs** — pricing overrides proposed by reconciliation and
|
|
73
|
+
* awaiting a human decision, searchable; the tab badge shows the
|
|
74
|
+
* pending count from anywhere in the console.
|
|
75
|
+
*
|
|
76
|
+
* Requires `can_manage_model_pricing` on `platform:stigmer` — render it
|
|
77
|
+
* only in operator-scoped surfaces (non-operators see the designed
|
|
78
|
+
* access notice). Rates shown are raw provider prices (pre-markup),
|
|
79
|
+
* not customer prices.
|
|
80
|
+
*
|
|
81
|
+
* @example
|
|
82
|
+
* ```tsx
|
|
83
|
+
* <PricingGovernanceConsole />
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export function PricingGovernanceConsole({
|
|
87
|
+
className,
|
|
88
|
+
defaultTab,
|
|
89
|
+
}: PricingGovernanceConsoleProps) {
|
|
90
|
+
const view = useModelGovernanceView();
|
|
91
|
+
// Seeded once from `defaultTab`, then owned locally (see the prop's
|
|
92
|
+
// JSDoc). The membership check is a public-API boundary guard: a JS
|
|
93
|
+
// consumer passing an out-of-union string must land on Models, not on
|
|
94
|
+
// a tabless surface.
|
|
95
|
+
const [activeTab, setActiveTab] = useState<PricingGovernanceTab>(() =>
|
|
96
|
+
defaultTab !== undefined && TABS.some((t) => t.id === defaultTab)
|
|
97
|
+
? defaultTab
|
|
98
|
+
: "models",
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
const { decide, isSubmitting: isDeciding, error: decisionError } = useDecidePricingOverride();
|
|
102
|
+
const { upsert, isSubmitting: isUpserting, error: upsertError, clearError: clearUpsertError } =
|
|
103
|
+
useUpsertModelPricingBaseline();
|
|
104
|
+
const { retire, isSubmitting: isRetiring, error: retireError, clearError: clearRetireError } =
|
|
105
|
+
useRetireModelPricingBaseline();
|
|
106
|
+
|
|
107
|
+
const handleDecide = useCallback(
|
|
108
|
+
async (overrideId: string, approve: boolean) => {
|
|
109
|
+
try {
|
|
110
|
+
await decide({ overrideId, approve });
|
|
111
|
+
// A decision changes both the pending queue and (on approval)
|
|
112
|
+
// the effective rates — reload the whole view.
|
|
113
|
+
view.refetch();
|
|
114
|
+
} catch {
|
|
115
|
+
// Surfaced via decisionError below.
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
[decide, view.refetch],
|
|
119
|
+
);
|
|
120
|
+
|
|
121
|
+
const handleUpsert = useCallback(
|
|
122
|
+
async (baseline: ModelPricingBaseline, revisionNote: string) => {
|
|
123
|
+
await upsert({ baseline, revisionNote: revisionNote || undefined });
|
|
124
|
+
view.refetch();
|
|
125
|
+
// An edit lands back on the (refreshed) detail; a create lands on
|
|
126
|
+
// the list — the new row's key is derivable but focusing it before
|
|
127
|
+
// the refetch resolves would show stale data.
|
|
128
|
+
if (view.flow.phase === "detail") view.backToDetail();
|
|
129
|
+
else view.backToList();
|
|
130
|
+
},
|
|
131
|
+
[upsert, view.refetch, view.flow.phase, view.backToDetail, view.backToList],
|
|
132
|
+
);
|
|
133
|
+
|
|
134
|
+
const handleCancelEdit = useCallback(() => {
|
|
135
|
+
clearUpsertError();
|
|
136
|
+
if (view.flow.phase === "detail") view.backToDetail();
|
|
137
|
+
else view.backToList();
|
|
138
|
+
}, [clearUpsertError, view.flow.phase, view.backToDetail, view.backToList]);
|
|
139
|
+
|
|
140
|
+
const handleRetire = useCallback(
|
|
141
|
+
async (target: ModelPricingBaseline, revisionNote: string) => {
|
|
142
|
+
await retire({
|
|
143
|
+
modelId: target.modelId,
|
|
144
|
+
provider: target.provider,
|
|
145
|
+
harness: target.harness,
|
|
146
|
+
revisionNote: revisionNote || undefined,
|
|
147
|
+
});
|
|
148
|
+
view.refetch();
|
|
149
|
+
view.backToList();
|
|
150
|
+
},
|
|
151
|
+
[retire, view.refetch, view.backToList],
|
|
152
|
+
);
|
|
153
|
+
|
|
154
|
+
const handleCancelRetire = useCallback(() => {
|
|
155
|
+
clearRetireError();
|
|
156
|
+
view.backToDetail();
|
|
157
|
+
}, [clearRetireError, view.backToDetail]);
|
|
158
|
+
|
|
159
|
+
if (view.isLoading) {
|
|
160
|
+
return (
|
|
161
|
+
<div className={cn("space-y-2", className)} aria-busy="true">
|
|
162
|
+
<div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
|
|
163
|
+
{Array.from({ length: 4 }, (_, i) => (
|
|
164
|
+
<div key={i} className="h-10 animate-pulse rounded-lg bg-muted-subtle" />
|
|
165
|
+
))}
|
|
166
|
+
</div>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
if (view.error) {
|
|
171
|
+
// A non-operator landing here is expected (the route is reachable by
|
|
172
|
+
// URL) — show the designed access notice, not a raw RPC error.
|
|
173
|
+
if (isPermissionDenied(view.error)) {
|
|
174
|
+
return <OperatorAccessNotice className={className} />;
|
|
175
|
+
}
|
|
176
|
+
return (
|
|
177
|
+
<p className={cn("text-destructive text-xs", className)} role="alert">
|
|
178
|
+
{getUserMessage(view.error)}
|
|
179
|
+
</p>
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return (
|
|
184
|
+
<Tabs
|
|
185
|
+
className={className}
|
|
186
|
+
tabs={[
|
|
187
|
+
TABS[0],
|
|
188
|
+
{ ...TABS[1], badge: view.pendingCount },
|
|
189
|
+
]}
|
|
190
|
+
activeTab={activeTab}
|
|
191
|
+
onTabChange={(id) => setActiveTab(id as PricingGovernanceTab)}
|
|
192
|
+
aria-label="Pricing governance sections"
|
|
193
|
+
>
|
|
194
|
+
{activeTab === "models" ? (
|
|
195
|
+
<ModelsTab
|
|
196
|
+
view={view}
|
|
197
|
+
isUpserting={isUpserting}
|
|
198
|
+
upsertError={upsertError}
|
|
199
|
+
onUpsert={handleUpsert}
|
|
200
|
+
onCancelEdit={handleCancelEdit}
|
|
201
|
+
isRetiring={isRetiring}
|
|
202
|
+
retireError={retireError}
|
|
203
|
+
onRetire={handleRetire}
|
|
204
|
+
onCancelRetire={handleCancelRetire}
|
|
205
|
+
/>
|
|
206
|
+
) : (
|
|
207
|
+
<SignOffsTab
|
|
208
|
+
view={view}
|
|
209
|
+
isDeciding={isDeciding}
|
|
210
|
+
decisionError={decisionError}
|
|
211
|
+
onDecide={handleDecide}
|
|
212
|
+
/>
|
|
213
|
+
)}
|
|
214
|
+
</Tabs>
|
|
215
|
+
);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// ---------------------------------------------------------------------------
|
|
219
|
+
// ModelsTab (internal)
|
|
220
|
+
// ---------------------------------------------------------------------------
|
|
221
|
+
|
|
222
|
+
function ModelsTab({
|
|
223
|
+
view,
|
|
224
|
+
isUpserting,
|
|
225
|
+
upsertError,
|
|
226
|
+
onUpsert,
|
|
227
|
+
onCancelEdit,
|
|
228
|
+
isRetiring,
|
|
229
|
+
retireError,
|
|
230
|
+
onRetire,
|
|
231
|
+
onCancelRetire,
|
|
232
|
+
}: {
|
|
233
|
+
readonly view: ReturnType<typeof useModelGovernanceView>;
|
|
234
|
+
readonly isUpserting: boolean;
|
|
235
|
+
readonly upsertError: Error | null;
|
|
236
|
+
readonly onUpsert: (baseline: ModelPricingBaseline, revisionNote: string) => Promise<void>;
|
|
237
|
+
readonly onCancelEdit: () => void;
|
|
238
|
+
readonly isRetiring: boolean;
|
|
239
|
+
readonly retireError: Error | null;
|
|
240
|
+
readonly onRetire: (target: ModelPricingBaseline, revisionNote: string) => Promise<void>;
|
|
241
|
+
readonly onCancelRetire: () => void;
|
|
242
|
+
}) {
|
|
243
|
+
const { flow, selected } = view;
|
|
244
|
+
|
|
245
|
+
if (flow.phase === "create") {
|
|
246
|
+
return (
|
|
247
|
+
<BaselineEditor
|
|
248
|
+
initial={null}
|
|
249
|
+
isSubmitting={isUpserting}
|
|
250
|
+
submitError={upsertError}
|
|
251
|
+
onSubmit={onUpsert}
|
|
252
|
+
onCancel={onCancelEdit}
|
|
253
|
+
/>
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
// A stale detail key (e.g. the model was just retired) falls through
|
|
258
|
+
// to the list rather than rendering an empty record.
|
|
259
|
+
if (flow.phase === "detail" && selected) {
|
|
260
|
+
if (flow.mode === "edit") {
|
|
261
|
+
return (
|
|
262
|
+
<BaselineEditor
|
|
263
|
+
initial={selected.baseline}
|
|
264
|
+
isSubmitting={isUpserting}
|
|
265
|
+
submitError={upsertError}
|
|
266
|
+
onSubmit={onUpsert}
|
|
267
|
+
onCancel={onCancelEdit}
|
|
268
|
+
/>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
if (flow.mode === "retire") {
|
|
272
|
+
return (
|
|
273
|
+
<RetireConfirm
|
|
274
|
+
target={selected.baseline}
|
|
275
|
+
isSubmitting={isRetiring}
|
|
276
|
+
submitError={retireError}
|
|
277
|
+
onConfirm={onRetire}
|
|
278
|
+
onCancel={onCancelRetire}
|
|
279
|
+
/>
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
return (
|
|
283
|
+
<ModelGovernanceDetail
|
|
284
|
+
row={selected}
|
|
285
|
+
onEdit={view.openEdit}
|
|
286
|
+
onRetire={view.openRetire}
|
|
287
|
+
onBack={view.backToList}
|
|
288
|
+
/>
|
|
289
|
+
);
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return (
|
|
293
|
+
<div className="space-y-3">
|
|
294
|
+
<div className="flex items-center justify-between gap-3">
|
|
295
|
+
<input
|
|
296
|
+
type="search"
|
|
297
|
+
className={cn(INPUT_CLASSES, "max-w-xs")}
|
|
298
|
+
value={view.modelQuery}
|
|
299
|
+
onChange={(e) => view.setModelQuery(e.target.value)}
|
|
300
|
+
placeholder="Search models…"
|
|
301
|
+
aria-label="Search models"
|
|
302
|
+
/>
|
|
303
|
+
<Button size="sm" onClick={view.openCreate}>
|
|
304
|
+
Add model
|
|
305
|
+
</Button>
|
|
306
|
+
</div>
|
|
307
|
+
|
|
308
|
+
<div className="rounded-lg border border-border bg-card">
|
|
309
|
+
{/* Presentational column guide — each row is a self-describing
|
|
310
|
+
button (its full text content is its accessible name), so
|
|
311
|
+
the header is a visual aid, not an ARIA table header. */}
|
|
312
|
+
<div
|
|
313
|
+
aria-hidden="true"
|
|
314
|
+
className="grid grid-cols-[2fr_1fr_1fr_1fr_0.7fr_1fr] gap-2 border-b border-border px-3 py-2 text-[11px] font-medium text-muted-foreground"
|
|
315
|
+
>
|
|
316
|
+
<span>Model</span>
|
|
317
|
+
<span>Harness</span>
|
|
318
|
+
<span className="text-right">Input</span>
|
|
319
|
+
<span className="text-right">Output</span>
|
|
320
|
+
<span className="text-right">Variants</span>
|
|
321
|
+
<span className="text-right">Governance</span>
|
|
322
|
+
</div>
|
|
323
|
+
{view.models.length === 0 ? (
|
|
324
|
+
<p className="px-3 py-2 text-xs text-muted-foreground">
|
|
325
|
+
{view.modelQuery.trim() !== ""
|
|
326
|
+
? `No models match "${view.modelQuery.trim()}".`
|
|
327
|
+
: "The catalog is empty — has the baseline seed migration run?"}
|
|
328
|
+
</p>
|
|
329
|
+
) : (
|
|
330
|
+
<ul role="list" aria-label="Models" className="m-0 list-none p-0">
|
|
331
|
+
{view.models.map((row) => (
|
|
332
|
+
<ModelRow key={row.key} row={row} onOpen={() => view.openDetail(row.key)} />
|
|
333
|
+
))}
|
|
334
|
+
</ul>
|
|
335
|
+
)}
|
|
336
|
+
</div>
|
|
337
|
+
</div>
|
|
338
|
+
);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* One model row: a real button (keyboard + AT support for "open the
|
|
343
|
+
* record" for free) laid out on the shared column grid. Its full text
|
|
344
|
+
* content is its accessible name, so AT users hear the same facts the
|
|
345
|
+
* columns show.
|
|
346
|
+
*/
|
|
347
|
+
function ModelRow({
|
|
348
|
+
row,
|
|
349
|
+
onOpen,
|
|
350
|
+
}: {
|
|
351
|
+
readonly row: ModelGovernanceRow;
|
|
352
|
+
readonly onOpen: () => void;
|
|
353
|
+
}) {
|
|
354
|
+
const { baseline, governance } = row;
|
|
355
|
+
const variantCount = Object.keys(baseline.pricingVariants).length;
|
|
356
|
+
const hasOverrides = (governance?.activeOverrides.length ?? 0) > 0;
|
|
357
|
+
|
|
358
|
+
return (
|
|
359
|
+
<li className="border-b border-border last:border-b-0">
|
|
360
|
+
<button
|
|
361
|
+
type="button"
|
|
362
|
+
onClick={onOpen}
|
|
363
|
+
className={cn(
|
|
364
|
+
"grid w-full grid-cols-[2fr_1fr_1fr_1fr_0.7fr_1fr] items-center gap-2 px-3 py-2 text-left text-xs",
|
|
365
|
+
"transition-colors hover:bg-accent",
|
|
366
|
+
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
|
|
367
|
+
)}
|
|
368
|
+
>
|
|
369
|
+
<span className="min-w-0">
|
|
370
|
+
<span className="block truncate font-medium text-foreground" title={baseline.modelId}>
|
|
371
|
+
{baseline.displayName || baseline.modelId}
|
|
372
|
+
</span>
|
|
373
|
+
<span className="block truncate text-[11px] text-muted-foreground">
|
|
374
|
+
{baseline.modelId}
|
|
375
|
+
{baseline.featured ? " · featured" : ""}
|
|
376
|
+
</span>
|
|
377
|
+
</span>
|
|
378
|
+
<span className="text-muted-foreground">{baseline.harness}</span>
|
|
379
|
+
<RateCell
|
|
380
|
+
baseline={baseline.pricing?.inputPriceMicrosPerMillion ?? ZERO}
|
|
381
|
+
effective={
|
|
382
|
+
governance?.effectiveInputMicrosPerMillion ??
|
|
383
|
+
baseline.pricing?.inputPriceMicrosPerMillion ??
|
|
384
|
+
ZERO
|
|
385
|
+
}
|
|
386
|
+
/>
|
|
387
|
+
<RateCell
|
|
388
|
+
baseline={baseline.pricing?.outputPriceMicrosPerMillion ?? ZERO}
|
|
389
|
+
effective={
|
|
390
|
+
governance?.effectiveOutputMicrosPerMillion ??
|
|
391
|
+
baseline.pricing?.outputPriceMicrosPerMillion ??
|
|
392
|
+
ZERO
|
|
393
|
+
}
|
|
394
|
+
/>
|
|
395
|
+
<span className="text-right text-muted-foreground">
|
|
396
|
+
{variantCount > 0 ? variantCount : "—"}
|
|
397
|
+
</span>
|
|
398
|
+
<span className="text-right">
|
|
399
|
+
{governance ? (
|
|
400
|
+
<GovernanceBadge
|
|
401
|
+
ledgerReconcilable={governance.ledgerReconcilable}
|
|
402
|
+
hasOverrides={hasOverrides}
|
|
403
|
+
/>
|
|
404
|
+
) : (
|
|
405
|
+
<span className="text-[10px] text-muted-foreground">—</span>
|
|
406
|
+
)}
|
|
407
|
+
</span>
|
|
408
|
+
</button>
|
|
409
|
+
</li>
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
// ---------------------------------------------------------------------------
|
|
414
|
+
// SignOffsTab (internal)
|
|
415
|
+
// ---------------------------------------------------------------------------
|
|
416
|
+
|
|
417
|
+
function SignOffsTab({
|
|
418
|
+
view,
|
|
419
|
+
isDeciding,
|
|
420
|
+
decisionError,
|
|
421
|
+
onDecide,
|
|
422
|
+
}: {
|
|
423
|
+
readonly view: ReturnType<typeof useModelGovernanceView>;
|
|
424
|
+
readonly isDeciding: boolean;
|
|
425
|
+
readonly decisionError: Error | null;
|
|
426
|
+
readonly onDecide: (overrideId: string, approve: boolean) => void;
|
|
427
|
+
}) {
|
|
428
|
+
return (
|
|
429
|
+
<div className="space-y-3">
|
|
430
|
+
<input
|
|
431
|
+
type="search"
|
|
432
|
+
className={cn(INPUT_CLASSES, "max-w-xs")}
|
|
433
|
+
value={view.signOffQuery}
|
|
434
|
+
onChange={(e) => view.setSignOffQuery(e.target.value)}
|
|
435
|
+
placeholder="Search sign-offs…"
|
|
436
|
+
aria-label="Search sign-offs"
|
|
437
|
+
/>
|
|
438
|
+
|
|
439
|
+
{decisionError && (
|
|
440
|
+
<p className="text-destructive text-xs" role="alert">
|
|
441
|
+
{getUserMessage(decisionError)}
|
|
442
|
+
</p>
|
|
443
|
+
)}
|
|
444
|
+
|
|
445
|
+
{view.pendingOverrides.length === 0 ? (
|
|
446
|
+
<p className="text-xs text-muted-foreground">
|
|
447
|
+
{view.signOffQuery.trim() !== ""
|
|
448
|
+
? `No pending sign-offs match "${view.signOffQuery.trim()}".`
|
|
449
|
+
: "No pricing overrides awaiting a decision."}
|
|
450
|
+
</p>
|
|
451
|
+
) : (
|
|
452
|
+
<div className="space-y-2">
|
|
453
|
+
{view.pendingOverrides.map((override) => (
|
|
454
|
+
<PendingOverrideCard
|
|
455
|
+
key={override.overrideId}
|
|
456
|
+
override={override}
|
|
457
|
+
isSubmitting={isDeciding}
|
|
458
|
+
onDecide={onDecide}
|
|
459
|
+
/>
|
|
460
|
+
))}
|
|
461
|
+
</div>
|
|
462
|
+
)}
|
|
463
|
+
</div>
|
|
464
|
+
);
|
|
465
|
+
}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { cn } from "@stigmer/theme";
|
|
4
|
+
import { getUserMessage, isPermissionDenied } from "@stigmer/sdk";
|
|
5
|
+
import type {
|
|
6
|
+
ModelPricingGovernanceEntry,
|
|
7
|
+
} from "@stigmer/protos/ai/stigmer/billing/v1/io_pb";
|
|
8
|
+
import { OperatorAccessNotice } from "./OperatorAccessNotice.js";
|
|
9
|
+
import { GovernanceBadge, PendingOverrideCard, RateCell } from "./governance-primitives.js";
|
|
10
|
+
import { usePricingGovernance } from "./usePricingGovernance.js";
|
|
11
|
+
import { useDecidePricingOverride } from "./useDecidePricingOverride.js";
|
|
12
|
+
|
|
13
|
+
/** Props for {@link PricingGovernancePanel}. */
|
|
14
|
+
export interface PricingGovernancePanelProps {
|
|
15
|
+
/** Additional CSS class names. */
|
|
16
|
+
readonly className?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Platform-operator panel for the pricing feedback loop: pending
|
|
21
|
+
* override sign-offs (approve/reject) and the effective-vs-baseline
|
|
22
|
+
* pricing state of every model.
|
|
23
|
+
*
|
|
24
|
+
* Prefer {@link PricingGovernanceConsole} for new surfaces — it
|
|
25
|
+
* composes this panel's content with the model catalog into one tabbed
|
|
26
|
+
* console. This standalone panel remains for consumers embedding just
|
|
27
|
+
* the governance view.
|
|
28
|
+
*
|
|
29
|
+
* Requires `can_manage_model_pricing` on `platform:stigmer` — render it
|
|
30
|
+
* only in operator-scoped surfaces. Rates shown are raw provider prices
|
|
31
|
+
* (pre-markup), not customer prices.
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```tsx
|
|
35
|
+
* <PricingGovernancePanel />
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
38
|
+
export function PricingGovernancePanel({ className }: PricingGovernancePanelProps) {
|
|
39
|
+
const { governance, isLoading, error, refetch } = usePricingGovernance();
|
|
40
|
+
const { decide, isSubmitting, error: decisionError } = useDecidePricingOverride();
|
|
41
|
+
|
|
42
|
+
if (isLoading) {
|
|
43
|
+
return (
|
|
44
|
+
<div className={cn("space-y-2", className)} aria-busy="true">
|
|
45
|
+
<div className="h-4 w-40 animate-pulse rounded bg-muted-subtle" />
|
|
46
|
+
{Array.from({ length: 4 }, (_, i) => (
|
|
47
|
+
<div key={i} className="h-10 animate-pulse rounded-lg bg-muted-subtle" />
|
|
48
|
+
))}
|
|
49
|
+
</div>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (error) {
|
|
54
|
+
// A non-operator landing here is expected (the route is reachable by
|
|
55
|
+
// URL) — show the designed access notice, not a raw RPC error.
|
|
56
|
+
if (isPermissionDenied(error)) {
|
|
57
|
+
return <OperatorAccessNotice className={className} />;
|
|
58
|
+
}
|
|
59
|
+
return (
|
|
60
|
+
<p className={cn("text-destructive text-xs", className)} role="alert">
|
|
61
|
+
{getUserMessage(error)}
|
|
62
|
+
</p>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (!governance) return null;
|
|
67
|
+
|
|
68
|
+
const onDecide = async (overrideId: string, approve: boolean) => {
|
|
69
|
+
try {
|
|
70
|
+
await decide({ overrideId, approve });
|
|
71
|
+
// A decision changes both the pending queue and (on approval) the
|
|
72
|
+
// effective rates — reload the whole view.
|
|
73
|
+
refetch();
|
|
74
|
+
} catch {
|
|
75
|
+
// Surfaced via decisionError below.
|
|
76
|
+
}
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<div className={cn("space-y-6", className)}>
|
|
81
|
+
<section aria-label="Pending pricing override proposals">
|
|
82
|
+
<h3 className="mb-2 text-xs font-semibold text-foreground">
|
|
83
|
+
Pending Sign-Offs
|
|
84
|
+
</h3>
|
|
85
|
+
{decisionError && (
|
|
86
|
+
<p className="mb-2 text-destructive text-xs" role="alert">
|
|
87
|
+
{getUserMessage(decisionError)}
|
|
88
|
+
</p>
|
|
89
|
+
)}
|
|
90
|
+
{governance.pendingOverrides.length === 0 ? (
|
|
91
|
+
<p className="text-xs text-muted-foreground">
|
|
92
|
+
No pricing overrides awaiting a decision.
|
|
93
|
+
</p>
|
|
94
|
+
) : (
|
|
95
|
+
<div className="space-y-2">
|
|
96
|
+
{governance.pendingOverrides.map((override) => (
|
|
97
|
+
<PendingOverrideCard
|
|
98
|
+
key={override.overrideId}
|
|
99
|
+
override={override}
|
|
100
|
+
isSubmitting={isSubmitting}
|
|
101
|
+
onDecide={onDecide}
|
|
102
|
+
/>
|
|
103
|
+
))}
|
|
104
|
+
</div>
|
|
105
|
+
)}
|
|
106
|
+
</section>
|
|
107
|
+
|
|
108
|
+
<section aria-label="Model pricing state">
|
|
109
|
+
<h3 className="mb-2 text-xs font-semibold text-foreground">
|
|
110
|
+
Model Pricing
|
|
111
|
+
</h3>
|
|
112
|
+
<div className="rounded-lg border border-border bg-card" role="table"
|
|
113
|
+
aria-label="Model pricing governance">
|
|
114
|
+
<div role="row"
|
|
115
|
+
className="grid grid-cols-[2fr_1fr_1fr_1fr_1fr] gap-2 border-b border-border px-3 py-2 text-[11px] font-medium text-muted-foreground">
|
|
116
|
+
<span role="columnheader">Model</span>
|
|
117
|
+
<span role="columnheader">Harness</span>
|
|
118
|
+
<span role="columnheader" className="text-right">Input</span>
|
|
119
|
+
<span role="columnheader" className="text-right">Output</span>
|
|
120
|
+
<span role="columnheader" className="text-right">Governance</span>
|
|
121
|
+
</div>
|
|
122
|
+
{governance.entries.map((entry) => (
|
|
123
|
+
<GovernanceRow
|
|
124
|
+
key={`${entry.modelId}-${entry.harness}-${entry.variant}`}
|
|
125
|
+
entry={entry}
|
|
126
|
+
/>
|
|
127
|
+
))}
|
|
128
|
+
</div>
|
|
129
|
+
</section>
|
|
130
|
+
</div>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ---------------------------------------------------------------------------
|
|
135
|
+
// GovernanceRow (internal)
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
|
|
138
|
+
function GovernanceRow({ entry }: { readonly entry: ModelPricingGovernanceEntry }) {
|
|
139
|
+
const hasOverrides = entry.activeOverrides.length > 0;
|
|
140
|
+
return (
|
|
141
|
+
<div role="row"
|
|
142
|
+
className="grid grid-cols-[2fr_1fr_1fr_1fr_1fr] items-center gap-2 border-b border-border px-3 py-2 text-xs last:border-b-0">
|
|
143
|
+
<span role="cell" className="truncate font-medium text-foreground"
|
|
144
|
+
title={entry.modelId}>
|
|
145
|
+
{entry.displayName || entry.modelId}
|
|
146
|
+
</span>
|
|
147
|
+
<span role="cell" className="text-muted-foreground">{entry.harness}</span>
|
|
148
|
+
<RateCell
|
|
149
|
+
role="cell"
|
|
150
|
+
baseline={entry.baselineInputMicrosPerMillion}
|
|
151
|
+
effective={entry.effectiveInputMicrosPerMillion}
|
|
152
|
+
/>
|
|
153
|
+
<RateCell
|
|
154
|
+
role="cell"
|
|
155
|
+
baseline={entry.baselineOutputMicrosPerMillion}
|
|
156
|
+
effective={entry.effectiveOutputMicrosPerMillion}
|
|
157
|
+
/>
|
|
158
|
+
<span role="cell" className="text-right">
|
|
159
|
+
<GovernanceBadge
|
|
160
|
+
ledgerReconcilable={entry.ledgerReconcilable}
|
|
161
|
+
hasOverrides={hasOverrides}
|
|
162
|
+
/>
|
|
163
|
+
</span>
|
|
164
|
+
</div>
|
|
165
|
+
);
|
|
166
|
+
}
|