@stigmer/react 3.2.3 → 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/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/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 +12 -6
- package/index.d.ts.map +1 -1
- package/index.js +14 -3
- package/index.js.map +1 -1
- package/library/index.d.ts +0 -7
- 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/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/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/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/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 +163 -13
- package/src/library/index.ts +0 -20
- 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/steps/ReviewStep.tsx +2 -3
- package/src/resource-creation/templates/workflow-templates.ts +4 -4
- 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/workflow/WorkflowYamlEditor.tsx +6 -270
- package/styles.css +1 -1
- package/workflow/CanvasTransitionEdge.d.ts +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/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/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
|
@@ -0,0 +1,619 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useCallback, useState, type FormEvent } from "react";
|
|
4
|
+
import { create } from "@bufbuild/protobuf";
|
|
5
|
+
import { getUserMessage } from "@stigmer/sdk";
|
|
6
|
+
import {
|
|
7
|
+
ModelPricingBaselineSchema,
|
|
8
|
+
PricingBlockSchema,
|
|
9
|
+
PricingVariantSchema,
|
|
10
|
+
type ModelPricingBaseline,
|
|
11
|
+
} from "@stigmer/protos/ai/stigmer/billing/v1/model_pricing_baseline_pb";
|
|
12
|
+
import { Button } from "../button/index.js";
|
|
13
|
+
import { Field, INPUT_CLASSES, RateField } from "./form-primitives.js";
|
|
14
|
+
import {
|
|
15
|
+
ZERO,
|
|
16
|
+
dollarsToMicros,
|
|
17
|
+
formatRate,
|
|
18
|
+
microsToDollarString,
|
|
19
|
+
} from "./pricing-format.js";
|
|
20
|
+
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// BaselineEditor — the add/edit form for model registry baselines, with an
|
|
23
|
+
// explicit old→new rate confirmation step (a billing-critical edit is never
|
|
24
|
+
// submitted without the operator seeing exactly which rates move).
|
|
25
|
+
//
|
|
26
|
+
// Internal to the billing module: rendered by PricingGovernanceConsole and
|
|
27
|
+
// ModelCatalogPanel, never exported from the barrel.
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
|
|
30
|
+
// ---------------------------------------------------------------------------
|
|
31
|
+
// Form model — strings while editing, converted + validated on submit.
|
|
32
|
+
// Validation mirrors the protovalidate rules on ModelPricingBaseline so
|
|
33
|
+
// errors surface before the RPC.
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
|
|
36
|
+
interface VariantForm {
|
|
37
|
+
readonly key: string;
|
|
38
|
+
readonly input: string;
|
|
39
|
+
readonly output: string;
|
|
40
|
+
readonly cacheWrite: string;
|
|
41
|
+
readonly cacheRead: string;
|
|
42
|
+
/** Comma-separated wire ids. */
|
|
43
|
+
readonly wireIds: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
interface CatalogForm {
|
|
47
|
+
readonly modelId: string;
|
|
48
|
+
readonly apiModelId: string;
|
|
49
|
+
readonly provider: string;
|
|
50
|
+
readonly harness: string;
|
|
51
|
+
readonly displayName: string;
|
|
52
|
+
readonly shortDescription: string;
|
|
53
|
+
readonly speedTier: string;
|
|
54
|
+
readonly costTier: string;
|
|
55
|
+
readonly featured: boolean;
|
|
56
|
+
readonly input: string;
|
|
57
|
+
readonly output: string;
|
|
58
|
+
readonly cacheWrite: string;
|
|
59
|
+
readonly cacheRead: string;
|
|
60
|
+
readonly cursorRate: string;
|
|
61
|
+
readonly variants: readonly VariantForm[];
|
|
62
|
+
readonly revisionNote: string;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const EMPTY_FORM: CatalogForm = {
|
|
66
|
+
modelId: "",
|
|
67
|
+
apiModelId: "",
|
|
68
|
+
provider: "",
|
|
69
|
+
harness: "native",
|
|
70
|
+
displayName: "",
|
|
71
|
+
shortDescription: "",
|
|
72
|
+
speedTier: "fast",
|
|
73
|
+
costTier: "standard",
|
|
74
|
+
featured: false,
|
|
75
|
+
input: "",
|
|
76
|
+
output: "",
|
|
77
|
+
cacheWrite: "0",
|
|
78
|
+
cacheRead: "0",
|
|
79
|
+
cursorRate: "",
|
|
80
|
+
variants: [],
|
|
81
|
+
revisionNote: "",
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
function formFromBaseline(baseline: ModelPricingBaseline): CatalogForm {
|
|
85
|
+
const pricing = baseline.pricing;
|
|
86
|
+
return {
|
|
87
|
+
modelId: baseline.modelId,
|
|
88
|
+
apiModelId: baseline.apiModelId,
|
|
89
|
+
provider: baseline.provider,
|
|
90
|
+
harness: baseline.harness,
|
|
91
|
+
displayName: baseline.displayName,
|
|
92
|
+
shortDescription: baseline.shortDescription,
|
|
93
|
+
speedTier: baseline.speedTier || "fast",
|
|
94
|
+
costTier: baseline.costTier || "standard",
|
|
95
|
+
featured: baseline.featured,
|
|
96
|
+
input: microsToDollarString(pricing?.inputPriceMicrosPerMillion ?? ZERO),
|
|
97
|
+
output: microsToDollarString(pricing?.outputPriceMicrosPerMillion ?? ZERO),
|
|
98
|
+
cacheWrite: microsToDollarString(pricing?.cacheWritePriceMicrosPerMillion ?? ZERO),
|
|
99
|
+
cacheRead: microsToDollarString(pricing?.cacheReadPriceMicrosPerMillion ?? ZERO),
|
|
100
|
+
cursorRate:
|
|
101
|
+
(pricing?.cursorTokenRateMicrosPerMillion ?? ZERO) > ZERO
|
|
102
|
+
? microsToDollarString(pricing!.cursorTokenRateMicrosPerMillion)
|
|
103
|
+
: "",
|
|
104
|
+
variants: Object.entries(baseline.pricingVariants).map(([key, variant]) => ({
|
|
105
|
+
key,
|
|
106
|
+
input: microsToDollarString(variant.pricing?.inputPriceMicrosPerMillion ?? ZERO),
|
|
107
|
+
output: microsToDollarString(variant.pricing?.outputPriceMicrosPerMillion ?? ZERO),
|
|
108
|
+
cacheWrite: microsToDollarString(variant.pricing?.cacheWritePriceMicrosPerMillion ?? ZERO),
|
|
109
|
+
cacheRead: microsToDollarString(variant.pricing?.cacheReadPriceMicrosPerMillion ?? ZERO),
|
|
110
|
+
wireIds: variant.wireIds.join(", "),
|
|
111
|
+
})),
|
|
112
|
+
revisionNote: "",
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Convert the form to a baseline proto, or return field-level errors.
|
|
118
|
+
*
|
|
119
|
+
* When editing, runtime metadata the form does not surface (context
|
|
120
|
+
* window, summarization, capabilities, per-block provenance) is carried
|
|
121
|
+
* over from the previous revision so a price edit never erases catalog
|
|
122
|
+
* documentation.
|
|
123
|
+
*/
|
|
124
|
+
function buildBaseline(
|
|
125
|
+
form: CatalogForm,
|
|
126
|
+
carryOver: ModelPricingBaseline | null,
|
|
127
|
+
): { baseline?: ModelPricingBaseline; errors: string[] } {
|
|
128
|
+
const errors: string[] = [];
|
|
129
|
+
const requireText = (value: string, label: string) => {
|
|
130
|
+
if (value.trim() === "") errors.push(`${label} is required.`);
|
|
131
|
+
return value.trim();
|
|
132
|
+
};
|
|
133
|
+
const requireRate = (value: string, label: string): bigint => {
|
|
134
|
+
const micros = dollarsToMicros(value);
|
|
135
|
+
if (micros === null) {
|
|
136
|
+
errors.push(`${label} must be a non-negative dollar amount.`);
|
|
137
|
+
return ZERO;
|
|
138
|
+
}
|
|
139
|
+
return micros;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
const modelId = requireText(form.modelId, "Model id");
|
|
143
|
+
const provider = requireText(form.provider, "Provider");
|
|
144
|
+
const harness = requireText(form.harness, "Harness");
|
|
145
|
+
const displayName = requireText(form.displayName, "Display name");
|
|
146
|
+
|
|
147
|
+
const input = requireRate(form.input, "Input rate");
|
|
148
|
+
const output = requireRate(form.output, "Output rate");
|
|
149
|
+
const cacheWrite = requireRate(form.cacheWrite, "Cache-write rate");
|
|
150
|
+
const cacheRead = requireRate(form.cacheRead, "Cache-read rate");
|
|
151
|
+
const cursorRate = form.cursorRate.trim() === "" ? ZERO : requireRate(form.cursorRate, "Cursor token rate");
|
|
152
|
+
|
|
153
|
+
const seenKeys = new Set<string>();
|
|
154
|
+
const variants: Record<string, ReturnType<typeof buildVariant>> = {};
|
|
155
|
+
for (const variant of form.variants) {
|
|
156
|
+
const key = variant.key.trim();
|
|
157
|
+
if (key === "") {
|
|
158
|
+
errors.push("Every variant needs a key (e.g. \"fast\").");
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
if (seenKeys.has(key)) {
|
|
162
|
+
errors.push(`Duplicate variant key "${key}".`);
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
seenKeys.add(key);
|
|
166
|
+
variants[key] = buildVariant(variant, key, carryOver, errors);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (errors.length > 0) return { errors };
|
|
170
|
+
|
|
171
|
+
const previousPricing = carryOver?.pricing;
|
|
172
|
+
const baseline = create(ModelPricingBaselineSchema, {
|
|
173
|
+
modelId,
|
|
174
|
+
apiModelId: form.apiModelId.trim(),
|
|
175
|
+
provider,
|
|
176
|
+
harness,
|
|
177
|
+
displayName,
|
|
178
|
+
shortDescription: form.shortDescription.trim(),
|
|
179
|
+
speedTier: form.speedTier,
|
|
180
|
+
costTier: form.costTier,
|
|
181
|
+
featured: form.featured,
|
|
182
|
+
pricing: create(PricingBlockSchema, {
|
|
183
|
+
inputPriceMicrosPerMillion: input,
|
|
184
|
+
outputPriceMicrosPerMillion: output,
|
|
185
|
+
cacheWritePriceMicrosPerMillion: cacheWrite,
|
|
186
|
+
cacheReadPriceMicrosPerMillion: cacheRead,
|
|
187
|
+
cursorTokenRateMicrosPerMillion: cursorRate,
|
|
188
|
+
// Provenance of an operator edit is the revision itself; keep the
|
|
189
|
+
// previous source string so "where did this rate come from" is
|
|
190
|
+
// never blanked by a UI edit. effective_at is server-stamped.
|
|
191
|
+
source: previousPricing?.source ?? "operator_console",
|
|
192
|
+
sourceNote: previousPricing?.sourceNote ?? "",
|
|
193
|
+
}),
|
|
194
|
+
pricingVariants: variants,
|
|
195
|
+
// Runtime metadata is not editable here — carry the previous
|
|
196
|
+
// revision's values so an edit never erases them.
|
|
197
|
+
contextWindowTokens: carryOver?.contextWindowTokens ?? 0,
|
|
198
|
+
maxOutputTokens: carryOver?.maxOutputTokens ?? 0,
|
|
199
|
+
tokenCounterMethod: carryOver?.tokenCounterMethod ?? "",
|
|
200
|
+
summarization: carryOver?.summarization,
|
|
201
|
+
capabilities: carryOver?.capabilities,
|
|
202
|
+
});
|
|
203
|
+
return { baseline, errors: [] };
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function buildVariant(
|
|
207
|
+
variant: VariantForm,
|
|
208
|
+
key: string,
|
|
209
|
+
carryOver: ModelPricingBaseline | null,
|
|
210
|
+
errors: string[],
|
|
211
|
+
) {
|
|
212
|
+
const rate = (value: string, label: string): bigint => {
|
|
213
|
+
const micros = dollarsToMicros(value);
|
|
214
|
+
if (micros === null) {
|
|
215
|
+
errors.push(`Variant "${key}" ${label} must be a non-negative dollar amount.`);
|
|
216
|
+
return ZERO;
|
|
217
|
+
}
|
|
218
|
+
return micros;
|
|
219
|
+
};
|
|
220
|
+
const previous = carryOver?.pricingVariants[key]?.pricing;
|
|
221
|
+
return create(PricingVariantSchema, {
|
|
222
|
+
pricing: create(PricingBlockSchema, {
|
|
223
|
+
inputPriceMicrosPerMillion: rate(variant.input, "input rate"),
|
|
224
|
+
outputPriceMicrosPerMillion: rate(variant.output, "output rate"),
|
|
225
|
+
cacheWritePriceMicrosPerMillion: rate(variant.cacheWrite, "cache-write rate"),
|
|
226
|
+
cacheReadPriceMicrosPerMillion: rate(variant.cacheRead, "cache-read rate"),
|
|
227
|
+
source: previous?.source ?? "operator_console",
|
|
228
|
+
sourceNote: previous?.sourceNote ?? "",
|
|
229
|
+
}),
|
|
230
|
+
wireIds: variant.wireIds
|
|
231
|
+
.split(",")
|
|
232
|
+
.map((w) => w.trim())
|
|
233
|
+
.filter((w) => w !== ""),
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// ---------------------------------------------------------------------------
|
|
238
|
+
// Rate diff for the confirmation step
|
|
239
|
+
// ---------------------------------------------------------------------------
|
|
240
|
+
|
|
241
|
+
interface RateChange {
|
|
242
|
+
readonly label: string;
|
|
243
|
+
readonly before: string;
|
|
244
|
+
readonly after: string;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function diffRates(
|
|
248
|
+
previous: ModelPricingBaseline | null,
|
|
249
|
+
next: ModelPricingBaseline,
|
|
250
|
+
): RateChange[] {
|
|
251
|
+
const changes: RateChange[] = [];
|
|
252
|
+
const compare = (label: string, before: bigint | undefined, after: bigint | undefined) => {
|
|
253
|
+
const b = before ?? ZERO;
|
|
254
|
+
const a = after ?? ZERO;
|
|
255
|
+
if (b !== a) {
|
|
256
|
+
changes.push({
|
|
257
|
+
label,
|
|
258
|
+
before: previous ? formatRate(b) : "—",
|
|
259
|
+
after: formatRate(a),
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
compare("Input", previous?.pricing?.inputPriceMicrosPerMillion, next.pricing?.inputPriceMicrosPerMillion);
|
|
265
|
+
compare("Output", previous?.pricing?.outputPriceMicrosPerMillion, next.pricing?.outputPriceMicrosPerMillion);
|
|
266
|
+
compare("Cache write", previous?.pricing?.cacheWritePriceMicrosPerMillion, next.pricing?.cacheWritePriceMicrosPerMillion);
|
|
267
|
+
compare("Cache read", previous?.pricing?.cacheReadPriceMicrosPerMillion, next.pricing?.cacheReadPriceMicrosPerMillion);
|
|
268
|
+
compare("Cursor token rate", previous?.pricing?.cursorTokenRateMicrosPerMillion, next.pricing?.cursorTokenRateMicrosPerMillion);
|
|
269
|
+
|
|
270
|
+
const variantKeys = new Set([
|
|
271
|
+
...Object.keys(previous?.pricingVariants ?? {}),
|
|
272
|
+
...Object.keys(next.pricingVariants),
|
|
273
|
+
]);
|
|
274
|
+
for (const key of variantKeys) {
|
|
275
|
+
const before = previous?.pricingVariants[key]?.pricing;
|
|
276
|
+
const after = next.pricingVariants[key]?.pricing;
|
|
277
|
+
if (!after) {
|
|
278
|
+
changes.push({ label: `Variant "${key}"`, before: "present", after: "removed" });
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
compare(`Variant "${key}" input`, before?.inputPriceMicrosPerMillion, after.inputPriceMicrosPerMillion);
|
|
282
|
+
compare(`Variant "${key}" output`, before?.outputPriceMicrosPerMillion, after.outputPriceMicrosPerMillion);
|
|
283
|
+
compare(`Variant "${key}" cache write`, before?.cacheWritePriceMicrosPerMillion, after.cacheWritePriceMicrosPerMillion);
|
|
284
|
+
compare(`Variant "${key}" cache read`, before?.cacheReadPriceMicrosPerMillion, after.cacheReadPriceMicrosPerMillion);
|
|
285
|
+
}
|
|
286
|
+
return changes;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// ---------------------------------------------------------------------------
|
|
290
|
+
// BaselineEditor — form step, then an explicit confirm step
|
|
291
|
+
// ---------------------------------------------------------------------------
|
|
292
|
+
|
|
293
|
+
export function BaselineEditor({
|
|
294
|
+
initial,
|
|
295
|
+
isSubmitting,
|
|
296
|
+
submitError,
|
|
297
|
+
onSubmit,
|
|
298
|
+
onCancel,
|
|
299
|
+
}: {
|
|
300
|
+
readonly initial: ModelPricingBaseline | null;
|
|
301
|
+
readonly isSubmitting: boolean;
|
|
302
|
+
readonly submitError: Error | null;
|
|
303
|
+
readonly onSubmit: (baseline: ModelPricingBaseline, revisionNote: string) => Promise<void>;
|
|
304
|
+
readonly onCancel: () => void;
|
|
305
|
+
}) {
|
|
306
|
+
const [form, setForm] = useState<CatalogForm>(
|
|
307
|
+
initial ? formFromBaseline(initial) : EMPTY_FORM,
|
|
308
|
+
);
|
|
309
|
+
const [validationErrors, setValidationErrors] = useState<string[]>([]);
|
|
310
|
+
const [pendingBaseline, setPendingBaseline] = useState<ModelPricingBaseline | null>(null);
|
|
311
|
+
|
|
312
|
+
const set = <K extends keyof CatalogForm>(field: K, value: CatalogForm[K]) =>
|
|
313
|
+
setForm((f) => ({ ...f, [field]: value }));
|
|
314
|
+
|
|
315
|
+
const handleReview = useCallback(
|
|
316
|
+
(e: FormEvent) => {
|
|
317
|
+
e.preventDefault();
|
|
318
|
+
const { baseline, errors } = buildBaseline(form, initial);
|
|
319
|
+
setValidationErrors(errors);
|
|
320
|
+
if (baseline) setPendingBaseline(baseline);
|
|
321
|
+
},
|
|
322
|
+
[form, initial],
|
|
323
|
+
);
|
|
324
|
+
|
|
325
|
+
const handleConfirm = useCallback(async () => {
|
|
326
|
+
if (!pendingBaseline) return;
|
|
327
|
+
try {
|
|
328
|
+
await onSubmit(pendingBaseline, form.revisionNote.trim());
|
|
329
|
+
} catch {
|
|
330
|
+
// Surfaced via submitError; return to the confirm view.
|
|
331
|
+
}
|
|
332
|
+
}, [pendingBaseline, form.revisionNote, onSubmit]);
|
|
333
|
+
|
|
334
|
+
// ── confirm step ──────────────────────────────────────────────────────────
|
|
335
|
+
if (pendingBaseline) {
|
|
336
|
+
const changes = diffRates(initial, pendingBaseline);
|
|
337
|
+
return (
|
|
338
|
+
<div className="space-y-3 rounded-lg border border-border bg-card px-3 py-3">
|
|
339
|
+
<h4 className="text-xs font-semibold text-foreground">
|
|
340
|
+
{initial ? "Confirm baseline revision" : "Confirm new catalog entry"}
|
|
341
|
+
{" · "}
|
|
342
|
+
<span className="font-normal text-muted-foreground">
|
|
343
|
+
{pendingBaseline.modelId} / {pendingBaseline.provider} / {pendingBaseline.harness}
|
|
344
|
+
</span>
|
|
345
|
+
</h4>
|
|
346
|
+
{changes.length === 0 ? (
|
|
347
|
+
<p className="text-xs text-muted-foreground">
|
|
348
|
+
No rate changes — only catalog fields move. Billing is unaffected.
|
|
349
|
+
</p>
|
|
350
|
+
) : (
|
|
351
|
+
<div className="space-y-1" role="table" aria-label="Rate changes">
|
|
352
|
+
{changes.map((change) => (
|
|
353
|
+
<p key={change.label} className="text-xs text-foreground" role="row">
|
|
354
|
+
<span className="text-muted-foreground">{change.label}: </span>
|
|
355
|
+
<span className="line-through">{change.before}</span>
|
|
356
|
+
{" → "}
|
|
357
|
+
<span className="font-medium">{change.after}</span>
|
|
358
|
+
</p>
|
|
359
|
+
))}
|
|
360
|
+
<p className="text-[11px] text-muted-foreground">
|
|
361
|
+
New rates govern charges from the moment this revision is applied
|
|
362
|
+
(forward-only; already-billed records keep their stamps).
|
|
363
|
+
</p>
|
|
364
|
+
</div>
|
|
365
|
+
)}
|
|
366
|
+
{submitError && (
|
|
367
|
+
<p className="text-destructive text-xs" role="alert">
|
|
368
|
+
{getUserMessage(submitError)}
|
|
369
|
+
</p>
|
|
370
|
+
)}
|
|
371
|
+
<div className="flex gap-2">
|
|
372
|
+
<Button size="sm" disabled={isSubmitting} onClick={handleConfirm}>
|
|
373
|
+
{isSubmitting ? "Applying…" : "Apply revision"}
|
|
374
|
+
</Button>
|
|
375
|
+
<Button
|
|
376
|
+
size="sm"
|
|
377
|
+
variant="outline"
|
|
378
|
+
disabled={isSubmitting}
|
|
379
|
+
onClick={() => setPendingBaseline(null)}
|
|
380
|
+
>
|
|
381
|
+
Back
|
|
382
|
+
</Button>
|
|
383
|
+
</div>
|
|
384
|
+
</div>
|
|
385
|
+
);
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// ── form step ─────────────────────────────────────────────────────────────
|
|
389
|
+
return (
|
|
390
|
+
<form
|
|
391
|
+
onSubmit={handleReview}
|
|
392
|
+
className="space-y-3 rounded-lg border border-border bg-card px-3 py-3"
|
|
393
|
+
>
|
|
394
|
+
<h4 className="text-xs font-semibold text-foreground">
|
|
395
|
+
{initial ? `Edit ${initial.modelId}` : "Add model"}
|
|
396
|
+
</h4>
|
|
397
|
+
|
|
398
|
+
<div className="grid grid-cols-2 gap-2">
|
|
399
|
+
<Field label="Model id" required>
|
|
400
|
+
<input
|
|
401
|
+
className={INPUT_CLASSES}
|
|
402
|
+
value={form.modelId}
|
|
403
|
+
onChange={(e) => set("modelId", e.target.value)}
|
|
404
|
+
placeholder="e.g. claude-sonnet-4.6"
|
|
405
|
+
// Identity is the catalog key: editing it would create a NEW
|
|
406
|
+
// entry, not revise this one — lock it on edit.
|
|
407
|
+
disabled={initial !== null || isSubmitting}
|
|
408
|
+
required
|
|
409
|
+
/>
|
|
410
|
+
</Field>
|
|
411
|
+
<Field label="Provider API id">
|
|
412
|
+
<input
|
|
413
|
+
className={INPUT_CLASSES}
|
|
414
|
+
value={form.apiModelId}
|
|
415
|
+
onChange={(e) => set("apiModelId", e.target.value)}
|
|
416
|
+
placeholder="e.g. claude-sonnet-4-6"
|
|
417
|
+
disabled={isSubmitting}
|
|
418
|
+
/>
|
|
419
|
+
</Field>
|
|
420
|
+
<Field label="Provider" required>
|
|
421
|
+
<input
|
|
422
|
+
className={INPUT_CLASSES}
|
|
423
|
+
value={form.provider}
|
|
424
|
+
onChange={(e) => set("provider", e.target.value)}
|
|
425
|
+
placeholder="e.g. anthropic"
|
|
426
|
+
disabled={initial !== null || isSubmitting}
|
|
427
|
+
required
|
|
428
|
+
/>
|
|
429
|
+
</Field>
|
|
430
|
+
<Field label="Harness" required>
|
|
431
|
+
<select
|
|
432
|
+
className={INPUT_CLASSES}
|
|
433
|
+
value={form.harness}
|
|
434
|
+
onChange={(e) => set("harness", e.target.value)}
|
|
435
|
+
disabled={initial !== null || isSubmitting}
|
|
436
|
+
>
|
|
437
|
+
<option value="native">native</option>
|
|
438
|
+
<option value="cursor">cursor</option>
|
|
439
|
+
</select>
|
|
440
|
+
</Field>
|
|
441
|
+
<Field label="Display name" required>
|
|
442
|
+
<input
|
|
443
|
+
className={INPUT_CLASSES}
|
|
444
|
+
value={form.displayName}
|
|
445
|
+
onChange={(e) => set("displayName", e.target.value)}
|
|
446
|
+
disabled={isSubmitting}
|
|
447
|
+
required
|
|
448
|
+
/>
|
|
449
|
+
</Field>
|
|
450
|
+
<Field label="Short description">
|
|
451
|
+
<input
|
|
452
|
+
className={INPUT_CLASSES}
|
|
453
|
+
value={form.shortDescription}
|
|
454
|
+
onChange={(e) => set("shortDescription", e.target.value)}
|
|
455
|
+
placeholder="3-6 word pitch"
|
|
456
|
+
disabled={isSubmitting}
|
|
457
|
+
/>
|
|
458
|
+
</Field>
|
|
459
|
+
<Field label="Speed tier">
|
|
460
|
+
<select
|
|
461
|
+
className={INPUT_CLASSES}
|
|
462
|
+
value={form.speedTier}
|
|
463
|
+
onChange={(e) => set("speedTier", e.target.value)}
|
|
464
|
+
disabled={isSubmitting}
|
|
465
|
+
>
|
|
466
|
+
<option value="fastest">fastest</option>
|
|
467
|
+
<option value="fast">fast</option>
|
|
468
|
+
<option value="balanced">balanced</option>
|
|
469
|
+
<option value="slow">slow</option>
|
|
470
|
+
</select>
|
|
471
|
+
</Field>
|
|
472
|
+
<Field label="Cost tier">
|
|
473
|
+
<select
|
|
474
|
+
className={INPUT_CLASSES}
|
|
475
|
+
value={form.costTier}
|
|
476
|
+
onChange={(e) => set("costTier", e.target.value)}
|
|
477
|
+
disabled={isSubmitting}
|
|
478
|
+
>
|
|
479
|
+
<option value="economy">economy</option>
|
|
480
|
+
<option value="standard">standard</option>
|
|
481
|
+
<option value="premium">premium</option>
|
|
482
|
+
</select>
|
|
483
|
+
</Field>
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<label className="flex cursor-pointer items-center gap-1.5 text-xs text-foreground">
|
|
487
|
+
<input
|
|
488
|
+
type="checkbox"
|
|
489
|
+
checked={form.featured}
|
|
490
|
+
onChange={(e) => set("featured", e.target.checked)}
|
|
491
|
+
disabled={isSubmitting}
|
|
492
|
+
/>
|
|
493
|
+
Featured (appears in the curated default picker list)
|
|
494
|
+
</label>
|
|
495
|
+
|
|
496
|
+
<fieldset className="space-y-2">
|
|
497
|
+
<legend className="text-xs font-medium text-foreground">
|
|
498
|
+
Rates ($ per million tokens)
|
|
499
|
+
</legend>
|
|
500
|
+
<div className="grid grid-cols-2 gap-2 sm:grid-cols-5">
|
|
501
|
+
<RateField label="Input" value={form.input} disabled={isSubmitting} onChange={(v) => set("input", v)} />
|
|
502
|
+
<RateField label="Output" value={form.output} disabled={isSubmitting} onChange={(v) => set("output", v)} />
|
|
503
|
+
<RateField label="Cache write" value={form.cacheWrite} disabled={isSubmitting} onChange={(v) => set("cacheWrite", v)} />
|
|
504
|
+
<RateField label="Cache read" value={form.cacheRead} disabled={isSubmitting} onChange={(v) => set("cacheRead", v)} />
|
|
505
|
+
<RateField
|
|
506
|
+
label="Cursor token rate"
|
|
507
|
+
value={form.cursorRate}
|
|
508
|
+
placeholder="cursor only"
|
|
509
|
+
disabled={isSubmitting}
|
|
510
|
+
onChange={(v) => set("cursorRate", v)}
|
|
511
|
+
/>
|
|
512
|
+
</div>
|
|
513
|
+
</fieldset>
|
|
514
|
+
|
|
515
|
+
<fieldset className="space-y-2">
|
|
516
|
+
<legend className="text-xs font-medium text-foreground">Pricing variants</legend>
|
|
517
|
+
{form.variants.map((variant, index) => (
|
|
518
|
+
<div key={index} className="space-y-2 rounded-md border border-border-muted px-2.5 py-2">
|
|
519
|
+
<div className="flex items-end gap-2">
|
|
520
|
+
<Field label="Variant key" className="w-32">
|
|
521
|
+
<input
|
|
522
|
+
className={INPUT_CLASSES}
|
|
523
|
+
value={variant.key}
|
|
524
|
+
onChange={(e) => updateVariant(setForm, index, { key: e.target.value })}
|
|
525
|
+
placeholder="fast"
|
|
526
|
+
disabled={isSubmitting}
|
|
527
|
+
/>
|
|
528
|
+
</Field>
|
|
529
|
+
<Field label="Wire ids (comma-separated)" className="flex-1">
|
|
530
|
+
<input
|
|
531
|
+
className={INPUT_CLASSES}
|
|
532
|
+
value={variant.wireIds}
|
|
533
|
+
onChange={(e) => updateVariant(setForm, index, { wireIds: e.target.value })}
|
|
534
|
+
placeholder="e.g. composer-2.5-fast"
|
|
535
|
+
disabled={isSubmitting}
|
|
536
|
+
/>
|
|
537
|
+
</Field>
|
|
538
|
+
<Button
|
|
539
|
+
size="sm"
|
|
540
|
+
variant="outline"
|
|
541
|
+
disabled={isSubmitting}
|
|
542
|
+
onClick={() =>
|
|
543
|
+
setForm((f) => ({
|
|
544
|
+
...f,
|
|
545
|
+
variants: f.variants.filter((_, i) => i !== index),
|
|
546
|
+
}))
|
|
547
|
+
}
|
|
548
|
+
>
|
|
549
|
+
Remove
|
|
550
|
+
</Button>
|
|
551
|
+
</div>
|
|
552
|
+
<div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
|
|
553
|
+
<RateField label="Input" value={variant.input} disabled={isSubmitting} onChange={(v) => updateVariant(setForm, index, { input: v })} />
|
|
554
|
+
<RateField label="Output" value={variant.output} disabled={isSubmitting} onChange={(v) => updateVariant(setForm, index, { output: v })} />
|
|
555
|
+
<RateField label="Cache write" value={variant.cacheWrite} disabled={isSubmitting} onChange={(v) => updateVariant(setForm, index, { cacheWrite: v })} />
|
|
556
|
+
<RateField label="Cache read" value={variant.cacheRead} disabled={isSubmitting} onChange={(v) => updateVariant(setForm, index, { cacheRead: v })} />
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
))}
|
|
560
|
+
<Button
|
|
561
|
+
size="sm"
|
|
562
|
+
variant="outline"
|
|
563
|
+
disabled={isSubmitting}
|
|
564
|
+
onClick={() =>
|
|
565
|
+
setForm((f) => ({
|
|
566
|
+
...f,
|
|
567
|
+
variants: [
|
|
568
|
+
...f.variants,
|
|
569
|
+
{ key: "", input: "", output: "", cacheWrite: "0", cacheRead: "0", wireIds: "" },
|
|
570
|
+
],
|
|
571
|
+
}))
|
|
572
|
+
}
|
|
573
|
+
>
|
|
574
|
+
Add variant
|
|
575
|
+
</Button>
|
|
576
|
+
</fieldset>
|
|
577
|
+
|
|
578
|
+
<Field label="Revision note">
|
|
579
|
+
<input
|
|
580
|
+
className={INPUT_CLASSES}
|
|
581
|
+
value={form.revisionNote}
|
|
582
|
+
onChange={(e) => set("revisionNote", e.target.value)}
|
|
583
|
+
placeholder="Why this revision (audit trail)"
|
|
584
|
+
disabled={isSubmitting}
|
|
585
|
+
/>
|
|
586
|
+
</Field>
|
|
587
|
+
|
|
588
|
+
{validationErrors.length > 0 && (
|
|
589
|
+
<div role="alert" className="space-y-0.5">
|
|
590
|
+
{validationErrors.map((message) => (
|
|
591
|
+
<p key={message} className="text-destructive text-xs">
|
|
592
|
+
{message}
|
|
593
|
+
</p>
|
|
594
|
+
))}
|
|
595
|
+
</div>
|
|
596
|
+
)}
|
|
597
|
+
|
|
598
|
+
<div className="flex gap-2">
|
|
599
|
+
<Button size="sm" type="submit" disabled={isSubmitting}>
|
|
600
|
+
Review changes
|
|
601
|
+
</Button>
|
|
602
|
+
<Button size="sm" variant="outline" disabled={isSubmitting} onClick={onCancel}>
|
|
603
|
+
Cancel
|
|
604
|
+
</Button>
|
|
605
|
+
</div>
|
|
606
|
+
</form>
|
|
607
|
+
);
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
function updateVariant(
|
|
611
|
+
setForm: (updater: (f: CatalogForm) => CatalogForm) => void,
|
|
612
|
+
index: number,
|
|
613
|
+
patch: Partial<VariantForm>,
|
|
614
|
+
) {
|
|
615
|
+
setForm((f) => ({
|
|
616
|
+
...f,
|
|
617
|
+
variants: f.variants.map((v, i) => (i === index ? { ...v, ...patch } : v)),
|
|
618
|
+
}));
|
|
619
|
+
}
|