@shipfox/client-agent 22.0.2 → 22.0.3
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/.storybook/preview.tsx +2 -2
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +19 -0
- package/dist/components/form-errors.d.ts.map +1 -1
- package/dist/components/form-errors.js +3 -0
- package/dist/components/form-errors.js.map +1 -1
- package/dist/components/harness-availability.d.ts +2 -2
- package/dist/components/harness-availability.d.ts.map +1 -1
- package/dist/components/harness-availability.js +4 -3
- package/dist/components/harness-availability.js.map +1 -1
- package/dist/components/harnesses-section.d.ts.map +1 -1
- package/dist/components/harnesses-section.js +4 -2
- package/dist/components/harnesses-section.js.map +1 -1
- package/dist/components/model-provider-usage-modal.d.ts.map +1 -1
- package/dist/components/model-provider-usage-modal.js +23 -5
- package/dist/components/model-provider-usage-modal.js.map +1 -1
- package/dist/components/model-provider-usage-target.d.ts +6 -6
- package/dist/components/model-provider-usage-target.d.ts.map +1 -1
- package/dist/components/model-provider-usage-target.js +3 -1
- package/dist/components/model-provider-usage-target.js.map +1 -1
- package/dist/components/model-providers-section.d.ts.map +1 -1
- package/dist/components/model-providers-section.js +277 -170
- package/dist/components/model-providers-section.js.map +1 -1
- package/dist/components/model-providers-section.stories.d.ts +2 -1
- package/dist/components/model-providers-section.stories.d.ts.map +1 -1
- package/dist/components/model-providers-section.stories.js +45 -1
- package/dist/components/model-providers-section.stories.js.map +1 -1
- package/dist/core/harness-policy.d.ts +5 -2
- package/dist/core/harness-policy.d.ts.map +1 -1
- package/dist/core/harness-policy.js +7 -1
- package/dist/core/harness-policy.js.map +1 -1
- package/dist/core/models.d.ts +3 -0
- package/dist/core/models.d.ts.map +1 -1
- package/dist/core/models.js.map +1 -1
- package/dist/core/provider-policy.d.ts +3 -1
- package/dist/core/provider-policy.d.ts.map +1 -1
- package/dist/core/provider-policy.js +7 -0
- package/dist/core/provider-policy.js.map +1 -1
- package/dist/hooks/api/model-provider-mapper.d.ts.map +1 -1
- package/dist/hooks/api/model-provider-mapper.js +5 -1
- package/dist/hooks/api/model-provider-mapper.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.d.ts +1 -1
- package/dist/pages/model-provider-onboarding-page.d.ts.map +1 -1
- package/dist/pages/model-provider-onboarding-page.js +58 -44
- package/dist/pages/model-provider-onboarding-page.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.d.ts.map +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js +5 -17
- package/dist/pages/model-provider-onboarding-page.stories.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/components/form-errors.test.ts +9 -0
- package/src/components/form-errors.ts +3 -0
- package/src/components/harness-availability.test.ts +49 -2
- package/src/components/harness-availability.ts +18 -3
- package/src/components/harnesses-section.test.tsx +51 -9
- package/src/components/harnesses-section.tsx +4 -1
- package/src/components/model-provider-usage-modal.test.tsx +23 -0
- package/src/components/model-provider-usage-modal.tsx +32 -6
- package/src/components/model-provider-usage-target.ts +9 -3
- package/src/components/model-providers-section.stories.tsx +33 -1
- package/src/components/model-providers-section.test.tsx +41 -0
- package/src/components/model-providers-section.tsx +264 -155
- package/src/core/harness-policy.ts +21 -1
- package/src/core/models.ts +3 -0
- package/src/core/provider-policy.ts +12 -0
- package/src/hooks/api/model-provider-mapper.test.ts +18 -0
- package/src/hooks/api/model-provider-mapper.ts +6 -1
- package/src/hooks/api/model-providers.test.ts +11 -0
- package/src/pages/model-provider-onboarding-page.stories.tsx +10 -14
- package/src/pages/model-provider-onboarding-page.test.tsx +133 -24
- package/src/pages/model-provider-onboarding-page.tsx +47 -34
- package/test/fixtures/model-providers.ts +22 -1
- package/tsconfig.build.tsbuildinfo +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/model-providers-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {useEffect, useMemo, useReducer, useRef, useState} from 'react';\nimport {\n type ManagementModal,\n managementModalReducer,\n} from '#core/model-provider-management-reducer.js';\nimport type {\n BuiltinProviderConfig,\n CustomProviderConfig,\n ProviderCatalogEntry,\n ProviderConfig,\n SupportedProvider,\n} from '#core/models.js';\nimport {\n customProviderCardMatchesSearch,\n isSupportedProvider,\n availableProviders as selectAvailableProviders,\n} from '#core/provider-policy.js';\nimport {\n useDeleteModelProviderConfigMutation,\n useModelProviderCatalogQuery,\n useModelProviderConfigsQuery,\n useSetDefaultModelProviderMutation,\n} from '#hooks/api/model-providers.js';\nimport {AddCustomProviderCard} from './add-custom-provider-card.js';\nimport {AvailableProvidersGrid} from './available-providers-grid.js';\nimport {ChangeDefaultModelForm} from './change-default-model-form.js';\nimport {CustomModelProviderForm} from './custom-model-provider-form.js';\nimport {modelProviderConfigErrorToFormError} from './form-errors.js';\nimport {ModelProviderGridSkeleton} from './model-provider-grid-skeleton.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n type ModelProviderUsageTarget,\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\nimport {ModelProviderTestAndSaveForm} from './test-and-save-form.js';\n\ntype UsageTarget = {\n target: ModelProviderUsageTarget;\n initialModel: string | null;\n restoreFocusToConfiguredProviders: boolean;\n};\n\nconst USAGE_MODAL_OPEN_DELAY_MS = 250;\n\nexport function WorkspaceModelProvidersSection({workspaceId}: {workspaceId: string}) {\n const catalogQuery = useModelProviderCatalogQuery();\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const [modal, dispatchModal] = useReducer(managementModalReducer, {kind: 'closed'});\n const [pendingUsageTarget, setPendingUsageTarget] = useState<UsageTarget | null>(null);\n const configuredProvidersRegionRef = useRef<HTMLElement | null>(null);\n\n const providers = catalogQuery.data?.providers ?? [];\n const configs = configsQuery.data?.configs ?? [];\n const configsLoaded = configsQuery.data !== undefined;\n const defaultProviderId = configsQuery.data?.defaultProviderId ?? null;\n const providerById = useMemo(\n () =>\n new Map<string, ProviderCatalogEntry>(providers.map((provider) => [provider.id, provider])),\n [providers],\n );\n const availableProviders = configsLoaded ? selectAvailableProviders(providers, configs) : [];\n const unsupportedProviders = providers.filter((provider) => !isSupportedProvider(provider));\n\n useEffect(() => {\n if (pendingUsageTarget === null || modal.kind !== 'closed') return undefined;\n\n const timer = window.setTimeout(() => {\n dispatchModal({\n type: 'show-usage',\n providerId: pendingUsageTarget.target.id,\n initialModel: pendingUsageTarget.initialModel,\n restoreFocusToConfiguredProviders: pendingUsageTarget.restoreFocusToConfiguredProviders,\n });\n setPendingUsageTarget(null);\n }, USAGE_MODAL_OPEN_DELAY_MS);\n\n return () => window.clearTimeout(timer);\n }, [modal.kind, pendingUsageTarget]);\n\n const usageTarget = useMemo(() => {\n if (modal.kind !== 'show-usage') return null;\n const config = configs.find((item) => item.providerId === modal.providerId);\n if (config?.kind === 'custom') return usageTargetFromCustomConfig(config);\n const entry = providerById.get(modal.providerId);\n return entry && isSupportedProvider(entry) ? usageTargetFromCatalogEntry(entry) : null;\n }, [configs, modal, providerById]);\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n <section\n ref={configuredProvidersRegionRef}\n className=\"flex flex-col gap-group outline-none\"\n aria-label=\"Configured providers\"\n tabIndex={-1}\n >\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Configured providers</Header>\n </div>\n\n {configsQuery.isPending ? (\n <ModelProviderRowsSkeleton label=\"Loading configured providers\" />\n ) : null}\n\n {configsQuery.isError && configsQuery.data === undefined ? (\n <Panel>\n <QueryLoadError query={configsQuery} subject=\"model provider configs\" variant=\"panel\" />\n </Panel>\n ) : null}\n\n {configsQuery.data !== undefined && configs.length === 0 ? (\n <Panel>\n <EmptyState\n icon=\"key2Line\"\n title=\"No providers configured\"\n description=\"Configure a provider below to run agent steps with workspace-managed credentials.\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {configs.length > 0 ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {configs.map((config) => {\n const catalogEntry = providerById.get(config.providerId);\n const entry =\n catalogEntry && isSupportedProvider(catalogEntry) ? catalogEntry : undefined;\n const builtinConfig = isBuiltinModelProviderConfig(config) ? config : undefined;\n const customConfig = isCustomModelProviderConfig(config) ? config : undefined;\n return (\n <ConfiguredProviderRow\n key={config.providerId}\n workspaceId={workspaceId}\n config={config}\n entry={entry}\n isDefault={config.providerId === defaultProviderId}\n onEdit={() => {\n if (entry && builtinConfig) {\n dispatchModal({\n type: 'edit-builtin',\n provider: entry,\n config: builtinConfig,\n });\n } else if (customConfig) {\n dispatchModal({type: 'edit-custom', config: customConfig});\n }\n }}\n onChangeDefaultModel={() => {\n if (entry && builtinConfig)\n dispatchModal({\n type: 'change-default-model',\n provider: entry,\n config: builtinConfig,\n });\n }}\n onShowUsage={() => {\n if (entry && builtinConfig) {\n setPendingUsageTarget(null);\n dispatchModal({\n type: 'show-usage',\n providerId: entry.id,\n initialModel: builtinConfig.defaultModel,\n restoreFocusToConfiguredProviders: false,\n });\n } else if (customConfig) {\n setPendingUsageTarget(null);\n dispatchModal({\n type: 'show-usage',\n providerId: customConfig.providerId,\n initialModel: customConfig.defaultModel,\n restoreFocusToConfiguredProviders: false,\n });\n }\n }}\n />\n );\n })}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n\n <section className=\"flex flex-col gap-group\" aria-label=\"Available providers\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Available providers</Header>\n </div>\n\n {catalogQuery.isPending || configsQuery.isPending ? (\n <ModelProviderGridSkeleton label=\"Loading available providers\" />\n ) : null}\n\n {catalogQuery.isError && catalogQuery.data === undefined ? (\n <Panel>\n <QueryLoadError query={catalogQuery} subject=\"model provider catalog\" variant=\"panel\" />\n </Panel>\n ) : null}\n\n {configsLoaded ? (\n <AvailableProvidersGrid\n entries={availableProviders}\n onSelect={(entry) => dispatchModal({type: 'configure-builtin', provider: entry})}\n trailingCard={\n <AddCustomProviderCard onConfigure={() => dispatchModal({type: 'create-custom'})} />\n }\n trailingCardMatchesSearch={customProviderCardMatchesSearch}\n />\n ) : null}\n </section>\n\n <section className=\"flex flex-col gap-group\" aria-label=\"Unsupported providers\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Unsupported providers</Header>\n </div>\n\n {catalogQuery.isPending ? (\n <ModelProviderRowsSkeleton label=\"Loading unsupported providers\" />\n ) : null}\n\n {unsupportedProviders.length > 0 ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {unsupportedProviders.map((entry) => (\n <PanelRow\n asChild\n className=\"items-start justify-start gap-cluster opacity-70 hover:bg-background-neutral-base\"\n key={entry.id}\n >\n <li>\n <Icon\n name=\"forbid2Line\"\n className=\"mt-[2px] size-18 shrink-0 text-foreground-neutral-muted\"\n aria-hidden\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <Text size=\"md\" bold className=\"truncate\">\n {entry.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {entry.unsupportedReason}\n </Text>\n </div>\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n\n <Modal\n open={modal.kind === 'configure-builtin' || modal.kind === 'edit-builtin'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">{modelProviderFormTitle(modal)}</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n {modelProviderFormTitle(modal)}\n </Text>\n </ModalHeader>\n {modal.kind === 'configure-builtin' || modal.kind === 'edit-builtin' ? (\n <ModelProviderTestAndSaveForm\n workspaceId={workspaceId}\n entry={modal.provider}\n existingConfig={modal.kind === 'edit-builtin' ? modal.config : undefined}\n onSaved={(savedDefaultModel) => {\n toast.success(`${modal.provider.label} saved`);\n if (modal.kind === 'configure-builtin' && configs.length === 0) {\n setPendingUsageTarget({\n target: usageTargetFromCatalogEntry(modal.provider),\n initialModel: savedDefaultModel,\n restoreFocusToConfiguredProviders: true,\n });\n }\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n\n <Modal\n open={modal.kind === 'change-default-model'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Change default model</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Change default model for{' '}\n {modal.kind === 'change-default-model' ? modal.provider.label : ''}\n </Text>\n </ModalHeader>\n {modal.kind === 'change-default-model' ? (\n <ChangeDefaultModelForm\n workspaceId={workspaceId}\n entry={modal.provider}\n config={modal.config}\n onSaved={() => {\n toast.success(`${modal.provider.label} default model saved`);\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n\n <ModelProviderUsageModal\n target={usageTarget}\n initialModel={modal.kind === 'show-usage' ? modal.initialModel : null}\n workspaceDefaultHarnessId={configsQuery.data?.defaultHarnessId ?? null}\n open={modal.kind === 'show-usage'}\n closeFocusTarget={\n modal.kind === 'show-usage' && modal.restoreFocusToConfiguredProviders\n ? configuredProvidersRegionRef.current\n : null\n }\n onOpenChange={(open) => {\n if (!open) dispatchModal({type: 'close'});\n }}\n />\n\n <Modal\n open={modal.kind === 'create-custom' || modal.kind === 'edit-custom'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent\n aria-describedby={undefined}\n className=\"max-h-[calc(100vh-32px)] max-w-[760px]\"\n >\n <ModalTitle className=\"sr-only\">{customModelProviderFormTitle(modal)}</ModalTitle>\n <ModalHeader>\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"lg\" aria-hidden=\"true\" className=\"truncate\">\n {customModelProviderFormTitle(modal)}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Connect an OpenAI-, Anthropic-, or Gemini-compatible endpoint.\n </Text>\n </div>\n </ModalHeader>\n {modal.kind === 'create-custom' || modal.kind === 'edit-custom' ? (\n <CustomModelProviderForm\n workspaceId={workspaceId}\n existingConfig={modal.kind === 'edit-custom' ? modal.config : undefined}\n onSaved={() => {\n toast.success(\n modal.kind === 'edit-custom'\n ? `${modal.config.displayName} saved`\n : 'Custom provider saved',\n );\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\nfunction modelProviderFormTitle(modal: ManagementModal): string {\n if (modal.kind === 'edit-builtin') return `Edit credentials for ${modal.provider.label}`;\n if (modal.kind === 'configure-builtin') return `Configure ${modal.provider.label}`;\n return '';\n}\n\nfunction customModelProviderFormTitle(modal: ManagementModal): string {\n if (modal.kind === 'edit-custom') return `Edit ${modal.config.displayName}`;\n return 'Add custom provider';\n}\n\nfunction isBuiltinModelProviderConfig(config: ProviderConfig): config is BuiltinProviderConfig {\n return config.kind === 'builtin';\n}\n\nfunction isCustomModelProviderConfig(config: ProviderConfig): config is CustomProviderConfig {\n return config.kind === 'custom';\n}\n\nfunction ConfiguredProviderRow({\n workspaceId,\n config,\n entry,\n isDefault,\n onEdit,\n onChangeDefaultModel,\n onShowUsage,\n}: {\n workspaceId: string;\n config: ProviderConfig;\n entry: SupportedProvider | undefined;\n isDefault: boolean;\n onEdit: () => void;\n onChangeDefaultModel: () => void;\n onShowUsage: () => void;\n}) {\n const setDefault = useSetDefaultModelProviderMutation();\n const deleteConfig = useDeleteModelProviderConfigMutation();\n const [defaultError, setDefaultError] = useState<string | undefined>();\n const [deleteOpen, setDeleteOpen] = useState(false);\n const [deleteError, setDeleteError] = useState<string | undefined>();\n const customConfig = isCustomModelProviderConfig(config) ? config : undefined;\n const label = customConfig?.displayName ?? entry?.label ?? config.providerId;\n const canUse = entry !== undefined || customConfig !== undefined;\n const canEdit = entry !== undefined || customConfig !== undefined;\n const isBuiltinConfig = isBuiltinModelProviderConfig(config);\n\n async function handleSetDefault() {\n setDefaultError(undefined);\n try {\n await setDefault.mutateAsync({\n workspaceId,\n providerId: config.providerId,\n });\n toast.success(`${label} is now the default provider`);\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n setDefaultError(mapped.message);\n }\n }\n\n async function handleDelete() {\n setDeleteError(undefined);\n try {\n await deleteConfig.mutateAsync({workspaceId, providerId: config.providerId});\n toast.success(`${label} deleted`);\n setDeleteOpen(false);\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n setDeleteError(mapped.message);\n }\n }\n\n function handleDeleteOpenChange(nextOpen: boolean) {\n setDeleteOpen(nextOpen);\n if (nextOpen) {\n setDeleteError(undefined);\n deleteConfig.reset();\n }\n }\n\n return (\n <PanelRow asChild className=\"flex-col items-stretch gap-inline\">\n <li>\n <div className=\"flex items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n {isDefault ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"starLine\"\n className=\"size-16 text-foreground-neutral-muted\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>Default provider</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">Default provider</span>\n </>\n ) : null}\n <Text size=\"md\" bold className=\"truncate\">\n {label}\n </Text>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${label} provider actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {!isDefault ? (\n <DropdownMenuItem\n icon=\"starLine\"\n disabled={setDefault.isPending || (!entry && !customConfig)}\n onSelect={() => {\n void handleSetDefault();\n }}\n >\n Set as default\n </DropdownMenuItem>\n ) : null}\n {isBuiltinConfig ? (\n <DropdownMenuItem\n icon=\"settings3Line\"\n disabled={!entry}\n onSelect={onChangeDefaultModel}\n >\n Change default model\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem icon=\"bookOpenLine\" disabled={!canUse} onSelect={onShowUsage}>\n View workflow example\n </DropdownMenuItem>\n <DropdownMenuItem icon=\"editLine\" disabled={!canEdit} onSelect={onEdit}>\n {customConfig ? 'Edit' : 'Edit credentials'}\n </DropdownMenuItem>\n <DropdownMenuItem\n icon=\"deleteBinLine\"\n onSelect={() => {\n setDeleteOpen(true);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n {defaultError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{defaultError}</Text>\n </Callout>\n ) : null}\n <DeleteModelProviderDialog\n open={deleteOpen}\n onOpenChange={handleDeleteOpenChange}\n label={label}\n errorMessage={deleteError}\n isLoading={deleteConfig.isPending}\n onDelete={handleDelete}\n />\n </li>\n </PanelRow>\n );\n}\n\nfunction DeleteModelProviderDialog({\n open,\n onOpenChange,\n label,\n errorMessage,\n isLoading,\n onDelete,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n label: string;\n errorMessage: string | undefined;\n isLoading: boolean;\n onDelete: () => void;\n}) {\n return (\n <Modal open={open} onOpenChange={onOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Delete model provider</ModalTitle>\n <ModalHeader title=\"Delete model provider\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Delete {label} credentials from this workspace? Agent jobs cannot use this provider\n until it is configured again.\n </Text>\n {errorMessage ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{errorMessage}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"danger\" isLoading={isLoading} onClick={onDelete}>\n Delete\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\nfunction ModelProviderRowsSkeleton({label}: {label: string}) {\n return (\n <Panel>\n <PanelBody asChild>\n <ul role=\"status\" aria-label={label}>\n {[0, 1, 2].map((row) => (\n <PanelRow\n asChild\n className=\"justify-start gap-cluster hover:bg-background-neutral-base\"\n key={row}\n >\n <li>\n <Skeleton className=\"size-32 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-inline\">\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"h-14 w-180\" />\n </div>\n <Skeleton className=\"h-28 w-96 shrink-0\" />\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n );\n}\n"],"names":["QueryLoadError","Button","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Icon","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","PanelBody","PanelRow","Skeleton","toast","Tooltip","TooltipContent","TooltipTrigger","Header","Text","useEffect","useMemo","useReducer","useRef","useState","managementModalReducer","customProviderCardMatchesSearch","isSupportedProvider","availableProviders","selectAvailableProviders","useDeleteModelProviderConfigMutation","useModelProviderCatalogQuery","useModelProviderConfigsQuery","useSetDefaultModelProviderMutation","AddCustomProviderCard","AvailableProvidersGrid","ChangeDefaultModelForm","CustomModelProviderForm","modelProviderConfigErrorToFormError","ModelProviderGridSkeleton","ModelProviderUsageModal","usageTargetFromCatalogEntry","usageTargetFromCustomConfig","ModelProviderTestAndSaveForm","USAGE_MODAL_OPEN_DELAY_MS","WorkspaceModelProvidersSection","workspaceId","catalogQuery","configsQuery","modal","dispatchModal","kind","pendingUsageTarget","setPendingUsageTarget","configuredProvidersRegionRef","providers","data","configs","configsLoaded","undefined","defaultProviderId","providerById","Map","map","provider","id","unsupportedProviders","filter","timer","window","setTimeout","type","providerId","target","initialModel","restoreFocusToConfiguredProviders","clearTimeout","usageTarget","config","find","item","entry","get","div","className","section","ref","aria-label","tabIndex","variant","isPending","ModelProviderRowsSkeleton","label","isError","query","subject","length","icon","title","description","asChild","ul","catalogEntry","builtinConfig","isBuiltinModelProviderConfig","customConfig","isCustomModelProviderConfig","ConfiguredProviderRow","isDefault","onEdit","onChangeDefaultModel","onShowUsage","defaultModel","entries","onSelect","trailingCard","onConfigure","trailingCardMatchesSearch","li","name","aria-hidden","size","bold","unsupportedReason","open","onOpenChange","aria-describedby","modelProviderFormTitle","existingConfig","onSaved","savedDefaultModel","success","workspaceDefaultHarnessId","defaultHarnessId","closeFocusTarget","current","customModelProviderFormTitle","displayName","setDefault","deleteConfig","defaultError","setDefaultError","deleteOpen","setDeleteOpen","deleteError","setDeleteError","canUse","canEdit","isBuiltinConfig","handleSetDefault","mutateAsync","error","mapped","message","handleDelete","handleDeleteOpenChange","nextOpen","reset","span","align","disabled","role","DeleteModelProviderDialog","errorMessage","isLoading","onDelete","onClick","row"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/model-providers-section.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button, IconButton} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuTrigger,\n} from '@shipfox/react-ui/dropdown-menu';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {\n Modal,\n ModalBody,\n ModalContent,\n ModalFooter,\n ModalHeader,\n ModalTitle,\n} from '@shipfox/react-ui/modal';\nimport {Panel, PanelBody, PanelRow} from '@shipfox/react-ui/panel';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Tooltip, TooltipContent, TooltipTrigger} from '@shipfox/react-ui/tooltip';\nimport {Code, Header, Text} from '@shipfox/react-ui/typography';\nimport {useEffect, useMemo, useReducer, useRef, useState} from 'react';\nimport {\n type ManagementModal,\n managementModalReducer,\n} from '#core/model-provider-management-reducer.js';\nimport type {\n BuiltinProviderConfig,\n CustomProviderConfig,\n ProviderCatalogEntry,\n ProviderConfig,\n SupportedProvider,\n} from '#core/models.js';\nimport {\n customProviderCardMatchesSearch,\n isManagedOnlyCatalog,\n isSupportedProvider,\n managedProviderFromCatalog,\n availableProviders as selectAvailableProviders,\n} from '#core/provider-policy.js';\nimport {\n useDeleteModelProviderConfigMutation,\n useModelProviderCatalogQuery,\n useModelProviderConfigsQuery,\n useSetDefaultModelProviderMutation,\n} from '#hooks/api/model-providers.js';\nimport {AddCustomProviderCard} from './add-custom-provider-card.js';\nimport {AvailableProvidersGrid} from './available-providers-grid.js';\nimport {ChangeDefaultModelForm} from './change-default-model-form.js';\nimport {CustomModelProviderForm} from './custom-model-provider-form.js';\nimport {modelProviderConfigErrorToFormError} from './form-errors.js';\nimport {ModelProviderGridSkeleton} from './model-provider-grid-skeleton.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n type ModelProviderUsageTarget,\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\nimport {ModelProviderTestAndSaveForm} from './test-and-save-form.js';\n\ntype UsageTarget = {\n target: ModelProviderUsageTarget;\n initialModel: string | null;\n restoreFocusToConfiguredProviders: boolean;\n};\n\nconst USAGE_MODAL_OPEN_DELAY_MS = 250;\n\nfunction ManagedProviderSection({\n provider,\n onShowUsage,\n}: {\n provider: SupportedProvider | undefined;\n onShowUsage: () => void;\n}) {\n return (\n <section className=\"flex flex-col gap-group\" aria-label=\"Managed provider\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Managed provider</Header>\n </div>\n\n {provider ? (\n <Panel>\n <PanelBody className=\"gap-group p-panel\">\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"md\" bold>\n {provider.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Managed by this instance. No workspace credentials are required.\n </Text>\n </div>\n\n <div className=\"flex flex-col gap-inline\">\n <Text size=\"sm\" bold>\n Available models ({provider.models.length})\n </Text>\n <ul\n aria-label={`${provider.label} models`}\n className=\"rounded-8 border border-border-neutral-base\"\n >\n {provider.models.map((model) => (\n <li\n key={model.id}\n className=\"flex min-w-0 items-center justify-between gap-inline border-b border-border-neutral-base px-row py-row last:border-b-0\"\n >\n <Text as=\"span\" size=\"sm\" bold className=\"min-w-0 truncate\">\n {model.label}\n </Text>\n <Code\n as=\"span\"\n variant=\"label\"\n className=\"min-w-0 truncate text-foreground-neutral-muted\"\n >\n {model.id}\n </Code>\n </li>\n ))}\n </ul>\n </div>\n\n <Button type=\"button\" size=\"sm\" variant=\"secondary\" onClick={onShowUsage}>\n Use in a workflow\n </Button>\n </PanelBody>\n </Panel>\n ) : (\n <Panel>\n <EmptyState\n icon=\"errorWarningLine\"\n title=\"Managed provider unavailable\"\n description=\"This instance is configured without workspace providers, but no managed provider was returned.\"\n variant=\"panel\"\n />\n </Panel>\n )}\n </section>\n );\n}\n\nexport function WorkspaceModelProvidersSection({workspaceId}: {workspaceId: string}) {\n const catalogQuery = useModelProviderCatalogQuery();\n const configsQuery = useModelProviderConfigsQuery(workspaceId);\n const [modal, dispatchModal] = useReducer(managementModalReducer, {kind: 'closed'});\n const [pendingUsageTarget, setPendingUsageTarget] = useState<UsageTarget | null>(null);\n const configuredProvidersRegionRef = useRef<HTMLElement | null>(null);\n\n const providers = catalogQuery.data?.providers ?? [];\n const configs = configsQuery.data?.configs ?? [];\n const configsLoaded = configsQuery.data !== undefined;\n const defaultProviderId = configsQuery.data?.defaultProviderId ?? null;\n const managedOnly = isManagedOnlyCatalog(catalogQuery.data);\n const managedProvider = managedProviderFromCatalog(catalogQuery.data);\n const providerById = useMemo(\n () =>\n new Map<string, ProviderCatalogEntry>(providers.map((provider) => [provider.id, provider])),\n [providers],\n );\n const availableProviders = configsLoaded ? selectAvailableProviders(providers, configs) : [];\n const unsupportedProviders = providers.filter((provider) => !isSupportedProvider(provider));\n\n useEffect(() => {\n if (pendingUsageTarget === null || modal.kind !== 'closed') return undefined;\n\n const timer = window.setTimeout(() => {\n dispatchModal({\n type: 'show-usage',\n providerId: pendingUsageTarget.target.id,\n initialModel: pendingUsageTarget.initialModel,\n restoreFocusToConfiguredProviders: pendingUsageTarget.restoreFocusToConfiguredProviders,\n });\n setPendingUsageTarget(null);\n }, USAGE_MODAL_OPEN_DELAY_MS);\n\n return () => window.clearTimeout(timer);\n }, [modal.kind, pendingUsageTarget]);\n\n const usageTarget = useMemo(() => {\n if (modal.kind !== 'show-usage') return null;\n const config = configs.find((item) => item.providerId === modal.providerId);\n if (config?.kind === 'custom') return usageTargetFromCustomConfig(config);\n const entry = providerById.get(modal.providerId);\n return entry && isSupportedProvider(entry)\n ? usageTargetFromCatalogEntry(entry, {isManaged: managedOnly})\n : null;\n }, [configs, managedOnly, modal, providerById]);\n\n return (\n <div className=\"flex min-w-0 flex-col gap-region\">\n {managedOnly ? (\n <ManagedProviderSection\n provider={managedProvider}\n onShowUsage={() => {\n if (!managedProvider) return;\n dispatchModal({\n type: 'show-usage',\n providerId: managedProvider.id,\n initialModel: managedProvider.defaultModel,\n restoreFocusToConfiguredProviders: false,\n });\n }}\n />\n ) : (\n <>\n <section\n ref={configuredProvidersRegionRef}\n className=\"flex flex-col gap-group outline-none\"\n aria-label=\"Configured providers\"\n tabIndex={-1}\n >\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Configured providers</Header>\n </div>\n\n {configsQuery.isPending ? (\n <ModelProviderRowsSkeleton label=\"Loading configured providers\" />\n ) : null}\n\n {configsQuery.isError && configsQuery.data === undefined ? (\n <Panel>\n <QueryLoadError\n query={configsQuery}\n subject=\"model provider configs\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {configsQuery.data !== undefined && configs.length === 0 ? (\n <Panel>\n <EmptyState\n icon=\"key2Line\"\n title=\"No providers configured\"\n description=\"Configure a provider below to run agent steps with workspace-managed credentials.\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {configs.length > 0 ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {configs.map((config) => {\n const catalogEntry = providerById.get(config.providerId);\n const entry =\n catalogEntry && isSupportedProvider(catalogEntry)\n ? catalogEntry\n : undefined;\n const builtinConfig = isBuiltinModelProviderConfig(config)\n ? config\n : undefined;\n const customConfig = isCustomModelProviderConfig(config) ? config : undefined;\n return (\n <ConfiguredProviderRow\n key={config.providerId}\n workspaceId={workspaceId}\n config={config}\n entry={entry}\n isDefault={config.providerId === defaultProviderId}\n onEdit={() => {\n if (entry && builtinConfig) {\n dispatchModal({\n type: 'edit-builtin',\n provider: entry,\n config: builtinConfig,\n });\n } else if (customConfig) {\n dispatchModal({type: 'edit-custom', config: customConfig});\n }\n }}\n onChangeDefaultModel={() => {\n if (entry && builtinConfig)\n dispatchModal({\n type: 'change-default-model',\n provider: entry,\n config: builtinConfig,\n });\n }}\n onShowUsage={() => {\n if (entry && builtinConfig) {\n setPendingUsageTarget(null);\n dispatchModal({\n type: 'show-usage',\n providerId: entry.id,\n initialModel: builtinConfig.defaultModel,\n restoreFocusToConfiguredProviders: false,\n });\n } else if (customConfig) {\n setPendingUsageTarget(null);\n dispatchModal({\n type: 'show-usage',\n providerId: customConfig.providerId,\n initialModel: customConfig.defaultModel,\n restoreFocusToConfiguredProviders: false,\n });\n }\n }}\n />\n );\n })}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n\n <section className=\"flex flex-col gap-group\" aria-label=\"Available providers\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Available providers</Header>\n </div>\n\n {catalogQuery.isPending || configsQuery.isPending ? (\n <ModelProviderGridSkeleton label=\"Loading available providers\" />\n ) : null}\n\n {catalogQuery.isError && catalogQuery.data === undefined ? (\n <Panel>\n <QueryLoadError\n query={catalogQuery}\n subject=\"model provider catalog\"\n variant=\"panel\"\n />\n </Panel>\n ) : null}\n\n {configsLoaded ? (\n <AvailableProvidersGrid\n entries={availableProviders}\n onSelect={(entry) => dispatchModal({type: 'configure-builtin', provider: entry})}\n trailingCard={\n <AddCustomProviderCard\n onConfigure={() => dispatchModal({type: 'create-custom'})}\n />\n }\n trailingCardMatchesSearch={customProviderCardMatchesSearch}\n />\n ) : null}\n </section>\n\n <section className=\"flex flex-col gap-group\" aria-label=\"Unsupported providers\">\n <div className=\"flex flex-col gap-tight\">\n <Header variant=\"h3\">Unsupported providers</Header>\n </div>\n\n {catalogQuery.isPending ? (\n <ModelProviderRowsSkeleton label=\"Loading unsupported providers\" />\n ) : null}\n\n {unsupportedProviders.length > 0 ? (\n <Panel>\n <PanelBody asChild>\n <ul>\n {unsupportedProviders.map((entry) => (\n <PanelRow\n asChild\n className=\"items-start justify-start gap-cluster opacity-70 hover:bg-background-neutral-base\"\n key={entry.id}\n >\n <li>\n <Icon\n name=\"forbid2Line\"\n className=\"mt-[2px] size-18 shrink-0 text-foreground-neutral-muted\"\n aria-hidden\n />\n <div className=\"flex min-w-0 flex-1 flex-col gap-tight\">\n <Text size=\"md\" bold className=\"truncate\">\n {entry.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {entry.unsupportedReason}\n </Text>\n </div>\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n ) : null}\n </section>\n </>\n )}\n\n <Modal\n open={modal.kind === 'configure-builtin' || modal.kind === 'edit-builtin'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">{modelProviderFormTitle(modal)}</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n {modelProviderFormTitle(modal)}\n </Text>\n </ModalHeader>\n {modal.kind === 'configure-builtin' || modal.kind === 'edit-builtin' ? (\n <ModelProviderTestAndSaveForm\n workspaceId={workspaceId}\n entry={modal.provider}\n existingConfig={modal.kind === 'edit-builtin' ? modal.config : undefined}\n onSaved={(savedDefaultModel) => {\n toast.success(`${modal.provider.label} saved`);\n if (modal.kind === 'configure-builtin' && configs.length === 0) {\n setPendingUsageTarget({\n target: usageTargetFromCatalogEntry(modal.provider),\n initialModel: savedDefaultModel,\n restoreFocusToConfiguredProviders: true,\n });\n }\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n\n <Modal\n open={modal.kind === 'change-default-model'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">Change default model</ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n Change default model for{' '}\n {modal.kind === 'change-default-model' ? modal.provider.label : ''}\n </Text>\n </ModalHeader>\n {modal.kind === 'change-default-model' ? (\n <ChangeDefaultModelForm\n workspaceId={workspaceId}\n entry={modal.provider}\n config={modal.config}\n onSaved={() => {\n toast.success(`${modal.provider.label} default model saved`);\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n\n <ModelProviderUsageModal\n target={usageTarget}\n initialModel={modal.kind === 'show-usage' ? modal.initialModel : null}\n workspaceDefaultHarnessId={configsQuery.data?.defaultHarnessId ?? null}\n open={modal.kind === 'show-usage'}\n closeFocusTarget={\n modal.kind === 'show-usage' && modal.restoreFocusToConfiguredProviders\n ? configuredProvidersRegionRef.current\n : null\n }\n onOpenChange={(open) => {\n if (!open) dispatchModal({type: 'close'});\n }}\n />\n\n <Modal\n open={modal.kind === 'create-custom' || modal.kind === 'edit-custom'}\n onOpenChange={(open) => (open ? undefined : dispatchModal({type: 'close'}))}\n >\n <ModalContent\n aria-describedby={undefined}\n className=\"max-h-[calc(100vh-32px)] max-w-[760px]\"\n >\n <ModalTitle className=\"sr-only\">{customModelProviderFormTitle(modal)}</ModalTitle>\n <ModalHeader>\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"lg\" aria-hidden=\"true\" className=\"truncate\">\n {customModelProviderFormTitle(modal)}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Connect an OpenAI-, Anthropic-, or Gemini-compatible endpoint.\n </Text>\n </div>\n </ModalHeader>\n {modal.kind === 'create-custom' || modal.kind === 'edit-custom' ? (\n <CustomModelProviderForm\n workspaceId={workspaceId}\n existingConfig={modal.kind === 'edit-custom' ? modal.config : undefined}\n onSaved={() => {\n toast.success(\n modal.kind === 'edit-custom'\n ? `${modal.config.displayName} saved`\n : 'Custom provider saved',\n );\n dispatchModal({type: 'close'});\n }}\n />\n ) : null}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\nfunction modelProviderFormTitle(modal: ManagementModal): string {\n if (modal.kind === 'edit-builtin') return `Edit credentials for ${modal.provider.label}`;\n if (modal.kind === 'configure-builtin') return `Configure ${modal.provider.label}`;\n return '';\n}\n\nfunction customModelProviderFormTitle(modal: ManagementModal): string {\n if (modal.kind === 'edit-custom') return `Edit ${modal.config.displayName}`;\n return 'Add custom provider';\n}\n\nfunction isBuiltinModelProviderConfig(config: ProviderConfig): config is BuiltinProviderConfig {\n return config.kind === 'builtin';\n}\n\nfunction isCustomModelProviderConfig(config: ProviderConfig): config is CustomProviderConfig {\n return config.kind === 'custom';\n}\n\nfunction ConfiguredProviderRow({\n workspaceId,\n config,\n entry,\n isDefault,\n onEdit,\n onChangeDefaultModel,\n onShowUsage,\n}: {\n workspaceId: string;\n config: ProviderConfig;\n entry: SupportedProvider | undefined;\n isDefault: boolean;\n onEdit: () => void;\n onChangeDefaultModel: () => void;\n onShowUsage: () => void;\n}) {\n const setDefault = useSetDefaultModelProviderMutation();\n const deleteConfig = useDeleteModelProviderConfigMutation();\n const [defaultError, setDefaultError] = useState<string | undefined>();\n const [deleteOpen, setDeleteOpen] = useState(false);\n const [deleteError, setDeleteError] = useState<string | undefined>();\n const customConfig = isCustomModelProviderConfig(config) ? config : undefined;\n const label = customConfig?.displayName ?? entry?.label ?? config.providerId;\n const canUse = entry !== undefined || customConfig !== undefined;\n const canEdit = entry !== undefined || customConfig !== undefined;\n const isBuiltinConfig = isBuiltinModelProviderConfig(config);\n\n async function handleSetDefault() {\n setDefaultError(undefined);\n try {\n await setDefault.mutateAsync({\n workspaceId,\n providerId: config.providerId,\n });\n toast.success(`${label} is now the default provider`);\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n setDefaultError(mapped.message);\n }\n }\n\n async function handleDelete() {\n setDeleteError(undefined);\n try {\n await deleteConfig.mutateAsync({workspaceId, providerId: config.providerId});\n toast.success(`${label} deleted`);\n setDeleteOpen(false);\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n setDeleteError(mapped.message);\n }\n }\n\n function handleDeleteOpenChange(nextOpen: boolean) {\n setDeleteOpen(nextOpen);\n if (nextOpen) {\n setDeleteError(undefined);\n deleteConfig.reset();\n }\n }\n\n return (\n <PanelRow asChild className=\"flex-col items-stretch gap-inline\">\n <li>\n <div className=\"flex items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 items-center gap-inline\">\n {isDefault ? (\n <>\n <Tooltip>\n <TooltipTrigger asChild>\n <span className=\"inline-flex size-16 shrink-0 items-center justify-center\">\n <Icon\n name=\"starLine\"\n className=\"size-16 text-foreground-neutral-muted\"\n aria-hidden\n />\n </span>\n </TooltipTrigger>\n <TooltipContent>Default provider</TooltipContent>\n </Tooltip>\n <span className=\"sr-only\">Default provider</span>\n </>\n ) : null}\n <Text size=\"md\" bold className=\"truncate\">\n {label}\n </Text>\n </div>\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <IconButton\n size=\"sm\"\n variant=\"transparent\"\n icon=\"more2Line\"\n aria-label={`Open ${label} provider actions`}\n />\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n {!isDefault ? (\n <DropdownMenuItem\n icon=\"starLine\"\n disabled={setDefault.isPending || (!entry && !customConfig)}\n onSelect={() => {\n void handleSetDefault();\n }}\n >\n Set as default\n </DropdownMenuItem>\n ) : null}\n {isBuiltinConfig ? (\n <DropdownMenuItem\n icon=\"settings3Line\"\n disabled={!entry}\n onSelect={onChangeDefaultModel}\n >\n Change default model\n </DropdownMenuItem>\n ) : null}\n <DropdownMenuItem icon=\"bookOpenLine\" disabled={!canUse} onSelect={onShowUsage}>\n View workflow example\n </DropdownMenuItem>\n <DropdownMenuItem icon=\"editLine\" disabled={!canEdit} onSelect={onEdit}>\n {customConfig ? 'Edit' : 'Edit credentials'}\n </DropdownMenuItem>\n <DropdownMenuItem\n icon=\"deleteBinLine\"\n onSelect={() => {\n setDeleteOpen(true);\n }}\n >\n Delete\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n </div>\n {defaultError ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{defaultError}</Text>\n </Callout>\n ) : null}\n <DeleteModelProviderDialog\n open={deleteOpen}\n onOpenChange={handleDeleteOpenChange}\n label={label}\n errorMessage={deleteError}\n isLoading={deleteConfig.isPending}\n onDelete={handleDelete}\n />\n </li>\n </PanelRow>\n );\n}\n\nfunction DeleteModelProviderDialog({\n open,\n onOpenChange,\n label,\n errorMessage,\n isLoading,\n onDelete,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n label: string;\n errorMessage: string | undefined;\n isLoading: boolean;\n onDelete: () => void;\n}) {\n return (\n <Modal open={open} onOpenChange={onOpenChange}>\n <ModalContent aria-describedby={undefined} className=\"max-w-[420px]\">\n <ModalTitle className=\"sr-only\">Delete model provider</ModalTitle>\n <ModalHeader title=\"Delete model provider\" />\n <ModalBody className=\"gap-group\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Delete {label} credentials from this workspace? Agent jobs cannot use this provider\n until it is configured again.\n </Text>\n {errorMessage ? (\n <Callout role=\"alert\" type=\"error\">\n <Text size=\"sm\">{errorMessage}</Text>\n </Callout>\n ) : null}\n </ModalBody>\n <ModalFooter>\n <Button size=\"sm\" variant=\"secondary\" onClick={() => onOpenChange(false)}>\n Cancel\n </Button>\n <Button size=\"sm\" variant=\"danger\" isLoading={isLoading} onClick={onDelete}>\n Delete\n </Button>\n </ModalFooter>\n </ModalContent>\n </Modal>\n );\n}\n\nfunction ModelProviderRowsSkeleton({label}: {label: string}) {\n return (\n <Panel>\n <PanelBody asChild>\n <ul role=\"status\" aria-label={label}>\n {[0, 1, 2].map((row) => (\n <PanelRow\n asChild\n className=\"justify-start gap-cluster hover:bg-background-neutral-base\"\n key={row}\n >\n <li>\n <Skeleton className=\"size-32 shrink-0\" />\n <div className=\"flex min-w-0 flex-1 flex-col gap-inline\">\n <Skeleton className=\"h-16 w-120\" />\n <Skeleton className=\"h-14 w-180\" />\n </div>\n <Skeleton className=\"h-28 w-96 shrink-0\" />\n </li>\n </PanelRow>\n ))}\n </ul>\n </PanelBody>\n </Panel>\n );\n}\n"],"names":["QueryLoadError","Button","IconButton","Callout","DropdownMenu","DropdownMenuContent","DropdownMenuItem","DropdownMenuTrigger","EmptyState","Icon","Modal","ModalBody","ModalContent","ModalFooter","ModalHeader","ModalTitle","Panel","PanelBody","PanelRow","Skeleton","toast","Tooltip","TooltipContent","TooltipTrigger","Code","Header","Text","useEffect","useMemo","useReducer","useRef","useState","managementModalReducer","customProviderCardMatchesSearch","isManagedOnlyCatalog","isSupportedProvider","managedProviderFromCatalog","availableProviders","selectAvailableProviders","useDeleteModelProviderConfigMutation","useModelProviderCatalogQuery","useModelProviderConfigsQuery","useSetDefaultModelProviderMutation","AddCustomProviderCard","AvailableProvidersGrid","ChangeDefaultModelForm","CustomModelProviderForm","modelProviderConfigErrorToFormError","ModelProviderGridSkeleton","ModelProviderUsageModal","usageTargetFromCatalogEntry","usageTargetFromCustomConfig","ModelProviderTestAndSaveForm","USAGE_MODAL_OPEN_DELAY_MS","ManagedProviderSection","provider","onShowUsage","section","className","aria-label","div","variant","size","bold","label","models","length","ul","map","model","li","as","id","type","onClick","icon","title","description","WorkspaceModelProvidersSection","workspaceId","catalogQuery","configsQuery","modal","dispatchModal","kind","pendingUsageTarget","setPendingUsageTarget","configuredProvidersRegionRef","providers","data","configs","configsLoaded","undefined","defaultProviderId","managedOnly","managedProvider","providerById","Map","unsupportedProviders","filter","timer","window","setTimeout","providerId","target","initialModel","restoreFocusToConfiguredProviders","clearTimeout","usageTarget","config","find","item","entry","get","isManaged","defaultModel","ref","tabIndex","isPending","ModelProviderRowsSkeleton","isError","query","subject","asChild","catalogEntry","builtinConfig","isBuiltinModelProviderConfig","customConfig","isCustomModelProviderConfig","ConfiguredProviderRow","isDefault","onEdit","onChangeDefaultModel","entries","onSelect","trailingCard","onConfigure","trailingCardMatchesSearch","name","aria-hidden","unsupportedReason","open","onOpenChange","aria-describedby","modelProviderFormTitle","existingConfig","onSaved","savedDefaultModel","success","workspaceDefaultHarnessId","defaultHarnessId","closeFocusTarget","current","customModelProviderFormTitle","displayName","setDefault","deleteConfig","defaultError","setDefaultError","deleteOpen","setDeleteOpen","deleteError","setDeleteError","canUse","canEdit","isBuiltinConfig","handleSetDefault","mutateAsync","error","mapped","message","handleDelete","handleDeleteOpenChange","nextOpen","reset","span","align","disabled","role","DeleteModelProviderDialog","errorMessage","isLoading","onDelete","row"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { StoryObj } from '@storybook/react';
|
|
2
|
-
type Scenario = 'mixed' | 'empty-configured' | 'all-configured' | 'custom-configured' | 'loading' | 'configs-error' | 'catalog-error' | 'long-names';
|
|
2
|
+
type Scenario = 'mixed' | 'empty-configured' | 'all-configured' | 'custom-configured' | 'loading' | 'configs-error' | 'catalog-error' | 'managed-only' | 'long-names';
|
|
3
3
|
interface ModelProvidersStoryProps {
|
|
4
4
|
scenario: Scenario;
|
|
5
5
|
}
|
|
@@ -17,6 +17,7 @@ declare const meta: {
|
|
|
17
17
|
export default meta;
|
|
18
18
|
type Story = StoryObj<typeof meta>;
|
|
19
19
|
export declare const Playground: Story;
|
|
20
|
+
export declare const ManagedOnly: Story;
|
|
20
21
|
export declare const EmptyConfigured: Story;
|
|
21
22
|
export declare const AllConfigured: Story;
|
|
22
23
|
export declare const CustomConfigured: Story;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-providers-section.stories.d.ts","sourceRoot":"","sources":["../../src/components/model-providers-section.stories.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAQrD,KAAK,QAAQ,GACT,OAAO,GACP,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,GACT,eAAe,GACf,eAAe,GACf,YAAY,CAAC;AAEjB,UAAU,wBAAwB;IAChC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AA+ED,iBAAS,mBAAmB,CAAC,EAAC,QAAQ,EAAC,EAAE,wBAAwB,+BAmBhE;AAED,QAAA,MAAM,IAAI;;;;QAGK,MAAM;;;;;CAEuB,CAAC;eAE9B,IAAI;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAUxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,KAU1C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAOhC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAOrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KAUtC,CAAC"}
|
|
1
|
+
{"version":3,"file":"model-providers-section.stories.d.ts","sourceRoot":"","sources":["../../src/components/model-providers-section.stories.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAO,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAQrD,KAAK,QAAQ,GACT,OAAO,GACP,kBAAkB,GAClB,gBAAgB,GAChB,mBAAmB,GACnB,SAAS,GACT,eAAe,GACf,eAAe,GACf,cAAc,GACd,YAAY,CAAC;AAEjB,UAAU,wBAAwB;IAChC,QAAQ,EAAE,QAAQ,CAAC;CACpB;AA+ED,iBAAS,mBAAmB,CAAC,EAAC,QAAQ,EAAC,EAAE,wBAAwB,+BAmBhE;AAED,QAAA,MAAM,IAAI;;;;QAGK,MAAM;;;;;CAEuB,CAAC;eAE9B,IAAI;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAC;AAEnC,eAAO,MAAM,UAAU,EAAE,KAAU,CAAC;AAEpC,eAAO,MAAM,WAAW,EAAE,KAOzB,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,KAE7B,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,KAE3B,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,KAE9B,CAAC;AAEF,eAAO,MAAM,OAAO,EAAE,KAErB,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,eAAO,MAAM,YAAY,EAAE,KAE1B,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,KAEvB,CAAC;AAEF,eAAO,MAAM,0BAA0B,EAAE,KAUxC,CAAC;AAEF,eAAO,MAAM,4BAA4B,EAAE,KAU1C,CAAC;AAEF,eAAO,MAAM,kBAAkB,EAAE,KAOhC,CAAC;AAEF,eAAO,MAAM,uBAAuB,EAAE,KAOrC,CAAC;AAEF,eAAO,MAAM,wBAAwB,EAAE,KAUtC,CAAC"}
|
|
@@ -171,6 +171,18 @@ const meta = {
|
|
|
171
171
|
};
|
|
172
172
|
export default meta;
|
|
173
173
|
export const Playground = {};
|
|
174
|
+
export const ManagedOnly = {
|
|
175
|
+
args: {
|
|
176
|
+
scenario: 'managed-only'
|
|
177
|
+
},
|
|
178
|
+
play: async ({ canvasElement })=>{
|
|
179
|
+
const canvas = within(canvasElement);
|
|
180
|
+
await canvas.findByText('Managed by this instance. No workspace credentials are required.');
|
|
181
|
+
await canvas.findByRole('button', {
|
|
182
|
+
name: 'Use in a workflow'
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
};
|
|
174
186
|
export const EmptyConfigured = {
|
|
175
187
|
args: {
|
|
176
188
|
scenario: 'empty-configured'
|
|
@@ -284,7 +296,10 @@ function fetchForScenario(scenario) {
|
|
|
284
296
|
if (url.pathname.endsWith('/agent/model-provider-catalog')) {
|
|
285
297
|
if (scenario === 'catalog-error') return Promise.resolve(errorResponse());
|
|
286
298
|
return Promise.resolve(jsonResponse({
|
|
287
|
-
providers: catalogForScenario(scenario)
|
|
299
|
+
providers: catalogForScenario(scenario),
|
|
300
|
+
...scenario === 'managed-only' ? {
|
|
301
|
+
workspace_providers: 'disabled'
|
|
302
|
+
} : {}
|
|
288
303
|
}));
|
|
289
304
|
}
|
|
290
305
|
if (url.pathname.endsWith('/agent/model-providers')) {
|
|
@@ -297,6 +312,28 @@ function fetchForScenario(scenario) {
|
|
|
297
312
|
};
|
|
298
313
|
}
|
|
299
314
|
function catalogForScenario(scenario) {
|
|
315
|
+
if (scenario === 'managed-only') {
|
|
316
|
+
return [
|
|
317
|
+
providerEntry({
|
|
318
|
+
id: 'shipfox',
|
|
319
|
+
label: 'Shipfox Managed',
|
|
320
|
+
default_model: 'claude-opus-4-8',
|
|
321
|
+
credential_fields: [],
|
|
322
|
+
models: [
|
|
323
|
+
{
|
|
324
|
+
id: 'claude-opus-4-8',
|
|
325
|
+
label: 'Claude Opus 4.8',
|
|
326
|
+
api: 'anthropic-messages'
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
id: 'gpt-5.5-pro',
|
|
330
|
+
label: 'GPT-5.5 Pro',
|
|
331
|
+
api: 'openai-responses'
|
|
332
|
+
}
|
|
333
|
+
]
|
|
334
|
+
})
|
|
335
|
+
];
|
|
336
|
+
}
|
|
300
337
|
if (scenario !== 'long-names') return CATALOG;
|
|
301
338
|
return [
|
|
302
339
|
providerEntry({
|
|
@@ -318,6 +355,13 @@ function catalogForScenario(scenario) {
|
|
|
318
355
|
];
|
|
319
356
|
}
|
|
320
357
|
function configsForScenario(scenario) {
|
|
358
|
+
if (scenario === 'managed-only') {
|
|
359
|
+
return {
|
|
360
|
+
configs: [],
|
|
361
|
+
default_provider_id: null,
|
|
362
|
+
default_harness_id: null
|
|
363
|
+
};
|
|
364
|
+
}
|
|
321
365
|
if (scenario === 'empty-configured' || scenario === 'configs-error') {
|
|
322
366
|
return {
|
|
323
367
|
configs: [],
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/model-providers-section.stories.tsx"],"sourcesContent":["import type {\n CustomModelProviderConfigDto,\n ModelProviderCatalogEntryDto,\n ModelProviderConfigDto,\n SupportedModelProviderId,\n} from '@shipfox/api-agent-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo} from 'react';\nimport {screen, userEvent, within} from 'storybook/test';\nimport {WorkspaceModelProvidersSection} from './model-providers-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'mixed'\n | 'empty-configured'\n | 'all-configured'\n | 'custom-configured'\n | 'loading'\n | 'configs-error'\n | 'catalog-error'\n | 'long-names';\n\ninterface ModelProvidersStoryProps {\n scenario: Scenario;\n}\n\nconst CATALOG: ModelProviderCatalogEntryDto[] = [\n providerEntry({\n id: 'anthropic',\n label: 'Anthropic',\n default_model: 'claude-opus-4-8',\n models: [\n {id: 'claude-opus-4-8', label: 'Claude Opus 4.8'},\n {id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5'},\n ],\n }),\n providerEntry({\n id: 'openai',\n label: 'OpenAI',\n default_model: 'gpt-5.5-pro',\n models: [\n {id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'},\n {id: 'gpt-5-mini', label: 'GPT-5 Mini'},\n ],\n }),\n providerEntry({\n id: 'xai',\n label: 'xAI',\n default_model: 'grok-code-fast-1',\n models: [{id: 'grok-code-fast-1', label: 'Grok Code Fast 1'}],\n }),\n providerEntry({\n id: 'openrouter',\n label: 'OpenRouter',\n default_model: 'openrouter/auto',\n models: [{id: 'openrouter/auto', label: 'OpenRouter Auto'}],\n }),\n providerEntry({\n id: 'google',\n label: 'Google Gemini',\n default_model: 'gemini-3-pro',\n models: [{id: 'gemini-3-pro', label: 'Gemini 3 Pro'}],\n }),\n providerEntry({\n id: 'mistral',\n label: 'Mistral AI',\n default_model: 'codestral-latest',\n models: [{id: 'codestral-latest', label: 'Codestral Latest'}],\n }),\n providerEntry({\n id: 'groq',\n label: 'Groq',\n default_model: 'llama-4-fast',\n models: [{id: 'llama-4-fast', label: 'Llama 4 Fast'}],\n }),\n providerEntry({\n id: 'deepseek',\n label: 'DeepSeek',\n default_model: 'deepseek-coder',\n models: [{id: 'deepseek-coder', label: 'DeepSeek Coder'}],\n }),\n providerEntry({\n id: 'moonshotai',\n label: 'Moonshot AI',\n default_model: 'kimi-k2',\n models: [{id: 'kimi-k2', label: 'Kimi K2'}],\n }),\n providerEntry({\n id: 'azure-openai-responses',\n label: 'Azure OpenAI Responses',\n default_model: 'gpt-5.5-pro',\n models: [{id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'}],\n }),\n providerEntry({\n id: 'amazon-bedrock',\n label: 'Amazon Bedrock',\n support_status: 'unsupported',\n credential_fields: [],\n unsupported_reason: 'AWS cloud credentials are not supported yet.',\n models: [],\n }),\n];\n\nfunction ModelProvidersStory({scenario}: ModelProvidersStoryProps) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"mx-auto w-full max-w-[760px] bg-background-subtle-base p-24\">\n <WorkspaceModelProvidersSection workspaceId={WORKSPACE_ID} />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderSettings',\n component: ModelProvidersStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'mixed'},\n} satisfies Meta<typeof ModelProvidersStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const EmptyConfigured: Story = {\n args: {scenario: 'empty-configured'},\n};\n\nexport const AllConfigured: Story = {\n args: {scenario: 'all-configured'},\n};\n\nexport const CustomConfigured: Story = {\n args: {scenario: 'custom-configured'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ConfigsError: Story = {\n args: {scenario: 'configs-error'},\n};\n\nexport const CatalogError: Story = {\n args: {scenario: 'catalog-error'},\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nexport const FilteredAvailableProviders: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.type(\n await canvas.findByRole('searchbox', {name: 'Search providers'}),\n 'openrouter',\n );\n await canvas.findByRole('button', {name: 'Configure OpenRouter'});\n },\n};\n\nexport const NoMatchingAvailableProviders: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.type(\n await canvas.findByRole('searchbox', {name: 'Search providers'}),\n 'not-a-provider',\n );\n await canvas.findByRole('button', {name: 'Clear search'});\n },\n};\n\nexport const ConfigureModalOpen: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure Anthropic'}));\n await screen.findByLabelText('API key');\n },\n};\n\nexport const CustomProviderModalOpen: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure custom provider'}));\n await screen.findByRole('dialog', {name: 'Add custom provider'});\n },\n};\n\nexport const WorkflowExampleModalOpen: Story = {\n args: {scenario: 'mixed'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(\n await canvas.findByRole('button', {name: 'Open Anthropic provider actions'}),\n );\n await userEvent.click(await screen.findByRole('menuitem', {name: 'View workflow example'}));\n await screen.findByRole('dialog', {name: 'Use Anthropic in a workflow'});\n },\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input) => {\n const url = requestUrl(input);\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (url.pathname.endsWith('/agent/model-provider-catalog')) {\n if (scenario === 'catalog-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse({providers: catalogForScenario(scenario)}));\n }\n if (url.pathname.endsWith('/agent/model-providers')) {\n if (scenario === 'configs-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse(configsForScenario(scenario)));\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction catalogForScenario(scenario: Scenario): ModelProviderCatalogEntryDto[] {\n if (scenario !== 'long-names') return CATALOG;\n return [\n providerEntry({\n id: 'anthropic',\n label: 'Anthropic Enterprise Production Claude Provider With Long Label',\n default_model: 'claude-opus-4-8',\n }),\n providerEntry({\n id: 'openai',\n label: 'OpenAI Platform Shared Workspace Credentials With Long Label',\n default_model: 'gpt-5.5-pro',\n models: [{id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'}],\n }),\n ];\n}\n\nfunction configsForScenario(scenario: Scenario) {\n if (scenario === 'empty-configured' || scenario === 'configs-error') {\n return {configs: [], default_provider_id: null, default_harness_id: null};\n }\n if (scenario === 'all-configured') {\n return {\n configs: CATALOG.filter((entry) => entry.support_status === 'supported').map((entry) =>\n providerConfig({\n provider_id: entry.id as SupportedModelProviderId,\n }),\n ),\n default_provider_id: 'anthropic',\n default_harness_id: null,\n };\n }\n if (scenario === 'custom-configured') {\n return {\n configs: [providerConfig({provider_id: 'anthropic'}), customProviderConfig()],\n default_provider_id: 'local-vllm',\n default_harness_id: null,\n };\n }\n return {\n configs: [providerConfig({provider_id: 'anthropic'})],\n default_provider_id: 'anthropic',\n default_harness_id: null,\n };\n}\n\nfunction customProviderConfig(): CustomModelProviderConfigDto {\n return {\n kind: 'custom',\n provider_id: 'local-vllm',\n display_name: 'Local vLLM',\n api: 'openai-completions',\n base_url: 'http://localhost:8000/v1',\n headers: [{name: 'x-region', value: 'us'}],\n secret_header_names: ['authorization'],\n models: [\n {id: 'llama-3.1', label: 'Llama 3.1'},\n {id: 'qwen-coder', label: 'Qwen Coder'},\n ],\n default_model: 'llama-3.1',\n created_at: '2026-05-08T00:00:00.000Z',\n updated_at: '2026-05-08T00:00:00.000Z',\n };\n}\n\nfunction providerEntry(\n overrides: Partial<ModelProviderCatalogEntryDto> = {},\n): ModelProviderCatalogEntryDto {\n return {\n id: 'anthropic',\n label: 'Anthropic',\n support_status: 'supported',\n default_model: null,\n credential_fields: [{key: 'api_key', label: 'API key', secret: true}],\n unsupported_reason: null,\n models: [{id: 'claude-opus-4-8', label: 'Claude Opus 4.8'}],\n ...overrides,\n };\n}\n\nfunction providerConfig(\n overrides: Partial<Omit<ModelProviderConfigDto, 'kind'>> = {},\n): ModelProviderConfigDto {\n return {\n kind: 'builtin',\n provider_id: 'anthropic',\n default_model: null,\n created_at: '2026-05-08T00:00:00.000Z',\n updated_at: '2026-05-08T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (typeof input === 'string') return new URL(input);\n if (input instanceof URL) return input;\n return new URL(input.url);\n}\n\nfunction jsonResponse(body: unknown, init: ResponseInit = {}) {\n return new Response(JSON.stringify(body), {\n status: 200,\n headers: {'content-type': 'application/json'},\n ...init,\n });\n}\n\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","Toaster","QueryClient","QueryClientProvider","useMemo","screen","userEvent","within","WorkspaceModelProvidersSection","WORKSPACE_ID","CATALOG","providerEntry","id","label","default_model","models","support_status","credential_fields","unsupported_reason","ModelProvidersStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","meta","title","component","parameters","layout","args","Playground","EmptyConfigured","AllConfigured","CustomConfigured","Loading","ConfigsError","CatalogError","LongNames","FilteredAvailableProviders","play","canvasElement","canvas","type","findByRole","name","NoMatchingAvailableProviders","ConfigureModalOpen","click","findByLabelText","CustomProviderModalOpen","WorkflowExampleModalOpen","input","url","requestUrl","Promise","undefined","pathname","endsWith","resolve","errorResponse","jsonResponse","providers","catalogForScenario","configsForScenario","status","configs","default_provider_id","default_harness_id","filter","entry","map","providerConfig","provider_id","customProviderConfig","kind","display_name","api","base_url","headers","value","secret_header_names","created_at","updated_at","overrides","key","secret","URL","body","init","Response","JSON","stringify","code","statusText"],"mappings":";AAMA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,OAAO,QAAO,0BAA0B;AAEhD,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SAAQC,OAAO,QAAO,QAAQ;AAC9B,SAAQC,MAAM,EAAEC,SAAS,EAAEC,MAAM,QAAO,iBAAiB;AACzD,SAAQC,8BAA8B,QAAO,+BAA+B;AAE5E,MAAMC,eAAe;AAgBrB,MAAMC,UAA0C;IAC9CC,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YACN;gBAACH,IAAI;gBAAmBC,OAAO;YAAiB;YAChD;gBAACD,IAAI;gBAAoBC,OAAO;YAAkB;SACnD;IACH;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YACN;gBAACH,IAAI;gBAAeC,OAAO;YAAa;YACxC;gBAACD,IAAI;gBAAcC,OAAO;YAAY;SACvC;IACH;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAoBC,OAAO;YAAkB;SAAE;IAC/D;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAmBC,OAAO;YAAiB;SAAE;IAC7D;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAgBC,OAAO;YAAc;SAAE;IACvD;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAoBC,OAAO;YAAkB;SAAE;IAC/D;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAgBC,OAAO;YAAc;SAAE;IACvD;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAkBC,OAAO;YAAgB;SAAE;IAC3D;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAWC,OAAO;YAAS;SAAE;IAC7C;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPC,eAAe;QACfC,QAAQ;YAAC;gBAACH,IAAI;gBAAeC,OAAO;YAAa;SAAE;IACrD;IACAF,cAAc;QACZC,IAAI;QACJC,OAAO;QACPG,gBAAgB;QAChBC,mBAAmB,EAAE;QACrBC,oBAAoB;QACpBH,QAAQ,EAAE;IACZ;CACD;AAED,SAASI,oBAAoB,EAACC,QAAQ,EAA2B;IAC/DpB,mBAAmB;QACjBqB,SAAS;QACTC,WAAWC,iBAAiBH;IAC9B;IAEA,MAAMI,cAAcpB,QAClB,IAAM,IAAIF,YAAY;YAACuB,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAGJ,qBACE,MAACxB;QAAoByB,QAAQJ;;0BAC3B,KAACK;gBAAIC,WAAU;0BACb,cAAA,KAACtB;oBAA+BuB,aAAatB;;;0BAE/C,KAACR;;;AAGP;AAEA,MAAM+B,OAAO;IACXC,OAAO;IACPC,WAAWf;IACXgB,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACjB,UAAU;IAAO;AAC1B;AAEA,eAAeY,KAAK;AAGpB,OAAO,MAAMM,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,kBAAyB;IACpCF,MAAM;QAACjB,UAAU;IAAkB;AACrC,EAAE;AAEF,OAAO,MAAMoB,gBAAuB;IAClCH,MAAM;QAACjB,UAAU;IAAgB;AACnC,EAAE;AAEF,OAAO,MAAMqB,mBAA0B;IACrCJ,MAAM;QAACjB,UAAU;IAAmB;AACtC,EAAE;AAEF,OAAO,MAAMsB,UAAiB;IAC5BL,MAAM;QAACjB,UAAU;IAAS;AAC5B,EAAE;AAEF,OAAO,MAAMuB,eAAsB;IACjCN,MAAM;QAACjB,UAAU;IAAe;AAClC,EAAE;AAEF,OAAO,MAAMwB,eAAsB;IACjCP,MAAM;QAACjB,UAAU;IAAe;AAClC,EAAE;AAEF,OAAO,MAAMyB,YAAmB;IAC9BR,MAAM;QAACjB,UAAU;IAAY;AAC/B,EAAE;AAEF,OAAO,MAAM0B,6BAAoC;IAC/CT,MAAM;QAACjB,UAAU;IAAkB;IACnC2B,MAAM,OAAO,EAACC,aAAa,EAAC;QAC1B,MAAMC,SAAS1C,OAAOyC;QACtB,MAAM1C,UAAU4C,IAAI,CAClB,MAAMD,OAAOE,UAAU,CAAC,aAAa;YAACC,MAAM;QAAkB,IAC9D;QAEF,MAAMH,OAAOE,UAAU,CAAC,UAAU;YAACC,MAAM;QAAsB;IACjE;AACF,EAAE;AAEF,OAAO,MAAMC,+BAAsC;IACjDhB,MAAM;QAACjB,UAAU;IAAkB;IACnC2B,MAAM,OAAO,EAACC,aAAa,EAAC;QAC1B,MAAMC,SAAS1C,OAAOyC;QACtB,MAAM1C,UAAU4C,IAAI,CAClB,MAAMD,OAAOE,UAAU,CAAC,aAAa;YAACC,MAAM;QAAkB,IAC9D;QAEF,MAAMH,OAAOE,UAAU,CAAC,UAAU;YAACC,MAAM;QAAc;IACzD;AACF,EAAE;AAEF,OAAO,MAAME,qBAA4B;IACvCjB,MAAM;QAACjB,UAAU;IAAkB;IACnC2B,MAAM,OAAO,EAACC,aAAa,EAAC;QAC1B,MAAMC,SAAS1C,OAAOyC;QACtB,MAAM1C,UAAUiD,KAAK,CAAC,MAAMN,OAAOE,UAAU,CAAC,UAAU;YAACC,MAAM;QAAqB;QACpF,MAAM/C,OAAOmD,eAAe,CAAC;IAC/B;AACF,EAAE;AAEF,OAAO,MAAMC,0BAAiC;IAC5CpB,MAAM;QAACjB,UAAU;IAAkB;IACnC2B,MAAM,OAAO,EAACC,aAAa,EAAC;QAC1B,MAAMC,SAAS1C,OAAOyC;QACtB,MAAM1C,UAAUiD,KAAK,CAAC,MAAMN,OAAOE,UAAU,CAAC,UAAU;YAACC,MAAM;QAA2B;QAC1F,MAAM/C,OAAO8C,UAAU,CAAC,UAAU;YAACC,MAAM;QAAqB;IAChE;AACF,EAAE;AAEF,OAAO,MAAMM,2BAAkC;IAC7CrB,MAAM;QAACjB,UAAU;IAAO;IACxB2B,MAAM,OAAO,EAACC,aAAa,EAAC;QAC1B,MAAMC,SAAS1C,OAAOyC;QACtB,MAAM1C,UAAUiD,KAAK,CACnB,MAAMN,OAAOE,UAAU,CAAC,UAAU;YAACC,MAAM;QAAiC;QAE5E,MAAM9C,UAAUiD,KAAK,CAAC,MAAMlD,OAAO8C,UAAU,CAAC,YAAY;YAACC,MAAM;QAAuB;QACxF,MAAM/C,OAAO8C,UAAU,CAAC,UAAU;YAACC,MAAM;QAA6B;IACxE;AACF,EAAE;AAEF,SAAS7B,iBAAiBH,QAAkB;IAC1C,OAAO,CAACuC;QACN,MAAMC,MAAMC,WAAWF;QACvB,IAAIvC,aAAa,WAAW,OAAO,IAAI0C,QAAkB,IAAMC;QAC/D,IAAIH,IAAII,QAAQ,CAACC,QAAQ,CAAC,kCAAkC;YAC1D,IAAI7C,aAAa,iBAAiB,OAAO0C,QAAQI,OAAO,CAACC;YACzD,OAAOL,QAAQI,OAAO,CAACE,aAAa;gBAACC,WAAWC,mBAAmBlD;YAAS;QAC9E;QACA,IAAIwC,IAAII,QAAQ,CAACC,QAAQ,CAAC,2BAA2B;YACnD,IAAI7C,aAAa,iBAAiB,OAAO0C,QAAQI,OAAO,CAACC;YACzD,OAAOL,QAAQI,OAAO,CAACE,aAAaG,mBAAmBnD;QACzD;QACA,OAAO0C,QAAQI,OAAO,CAACE,aAAa,CAAC,GAAG;YAACI,QAAQ;QAAG;IACtD;AACF;AAEA,SAASF,mBAAmBlD,QAAkB;IAC5C,IAAIA,aAAa,cAAc,OAAOV;IACtC,OAAO;QACLC,cAAc;YACZC,IAAI;YACJC,OAAO;YACPC,eAAe;QACjB;QACAH,cAAc;YACZC,IAAI;YACJC,OAAO;YACPC,eAAe;YACfC,QAAQ;gBAAC;oBAACH,IAAI;oBAAeC,OAAO;gBAAa;aAAE;QACrD;KACD;AACH;AAEA,SAAS0D,mBAAmBnD,QAAkB;IAC5C,IAAIA,aAAa,sBAAsBA,aAAa,iBAAiB;QACnE,OAAO;YAACqD,SAAS,EAAE;YAAEC,qBAAqB;YAAMC,oBAAoB;QAAI;IAC1E;IACA,IAAIvD,aAAa,kBAAkB;QACjC,OAAO;YACLqD,SAAS/D,QAAQkE,MAAM,CAAC,CAACC,QAAUA,MAAM7D,cAAc,KAAK,aAAa8D,GAAG,CAAC,CAACD,QAC5EE,eAAe;oBACbC,aAAaH,MAAMjE,EAAE;gBACvB;YAEF8D,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,IAAIvD,aAAa,qBAAqB;QACpC,OAAO;YACLqD,SAAS;gBAACM,eAAe;oBAACC,aAAa;gBAAW;gBAAIC;aAAuB;YAC7EP,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,OAAO;QACLF,SAAS;YAACM,eAAe;gBAACC,aAAa;YAAW;SAAG;QACrDN,qBAAqB;QACrBC,oBAAoB;IACtB;AACF;AAEA,SAASM;IACP,OAAO;QACLC,MAAM;QACNF,aAAa;QACbG,cAAc;QACdC,KAAK;QACLC,UAAU;QACVC,SAAS;YAAC;gBAAClC,MAAM;gBAAYmC,OAAO;YAAI;SAAE;QAC1CC,qBAAqB;YAAC;SAAgB;QACtCzE,QAAQ;YACN;gBAACH,IAAI;gBAAaC,OAAO;YAAW;YACpC;gBAACD,IAAI;gBAAcC,OAAO;YAAY;SACvC;QACDC,eAAe;QACf2E,YAAY;QACZC,YAAY;IACd;AACF;AAEA,SAAS/E,cACPgF,YAAmD,CAAC,CAAC;IAErD,OAAO;QACL/E,IAAI;QACJC,OAAO;QACPG,gBAAgB;QAChBF,eAAe;QACfG,mBAAmB;YAAC;gBAAC2E,KAAK;gBAAW/E,OAAO;gBAAWgF,QAAQ;YAAI;SAAE;QACrE3E,oBAAoB;QACpBH,QAAQ;YAAC;gBAACH,IAAI;gBAAmBC,OAAO;YAAiB;SAAE;QAC3D,GAAG8E,SAAS;IACd;AACF;AAEA,SAASZ,eACPY,YAA2D,CAAC,CAAC;IAE7D,OAAO;QACLT,MAAM;QACNF,aAAa;QACblE,eAAe;QACf2E,YAAY;QACZC,YAAY;QACZ,GAAGC,SAAS;IACd;AACF;AAEA,SAAS9B,WAAWF,KAAwB;IAC1C,IAAI,OAAOA,UAAU,UAAU,OAAO,IAAImC,IAAInC;IAC9C,IAAIA,iBAAiBmC,KAAK,OAAOnC;IACjC,OAAO,IAAImC,IAAInC,MAAMC,GAAG;AAC1B;AAEA,SAASQ,aAAa2B,IAAa,EAAEC,OAAqB,CAAC,CAAC;IAC1D,OAAO,IAAIC,SAASC,KAAKC,SAAS,CAACJ,OAAO;QACxCvB,QAAQ;QACRc,SAAS;YAAC,gBAAgB;QAAkB;QAC5C,GAAGU,IAAI;IACT;AACF;AAEA,SAAS7B;IACP,OAAOC,aAAa;QAACgC,MAAM;IAAc,GAAG;QAAC5B,QAAQ;QAAK6B,YAAY;IAAc;AACtF"}
|
|
1
|
+
{"version":3,"sources":["../../src/components/model-providers-section.stories.tsx"],"sourcesContent":["import type {\n CustomModelProviderConfigDto,\n ModelProviderCatalogEntryDto,\n ModelProviderConfigDto,\n SupportedModelProviderId,\n} from '@shipfox/api-agent-dto';\nimport {configureApiClient} from '@shipfox/client-api';\nimport {Toaster} from '@shipfox/react-ui/toast';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo} from 'react';\nimport {screen, userEvent, within} from 'storybook/test';\nimport {WorkspaceModelProvidersSection} from './model-providers-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'mixed'\n | 'empty-configured'\n | 'all-configured'\n | 'custom-configured'\n | 'loading'\n | 'configs-error'\n | 'catalog-error'\n | 'managed-only'\n | 'long-names';\n\ninterface ModelProvidersStoryProps {\n scenario: Scenario;\n}\n\nconst CATALOG: ModelProviderCatalogEntryDto[] = [\n providerEntry({\n id: 'anthropic',\n label: 'Anthropic',\n default_model: 'claude-opus-4-8',\n models: [\n {id: 'claude-opus-4-8', label: 'Claude Opus 4.8'},\n {id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5'},\n ],\n }),\n providerEntry({\n id: 'openai',\n label: 'OpenAI',\n default_model: 'gpt-5.5-pro',\n models: [\n {id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'},\n {id: 'gpt-5-mini', label: 'GPT-5 Mini'},\n ],\n }),\n providerEntry({\n id: 'xai',\n label: 'xAI',\n default_model: 'grok-code-fast-1',\n models: [{id: 'grok-code-fast-1', label: 'Grok Code Fast 1'}],\n }),\n providerEntry({\n id: 'openrouter',\n label: 'OpenRouter',\n default_model: 'openrouter/auto',\n models: [{id: 'openrouter/auto', label: 'OpenRouter Auto'}],\n }),\n providerEntry({\n id: 'google',\n label: 'Google Gemini',\n default_model: 'gemini-3-pro',\n models: [{id: 'gemini-3-pro', label: 'Gemini 3 Pro'}],\n }),\n providerEntry({\n id: 'mistral',\n label: 'Mistral AI',\n default_model: 'codestral-latest',\n models: [{id: 'codestral-latest', label: 'Codestral Latest'}],\n }),\n providerEntry({\n id: 'groq',\n label: 'Groq',\n default_model: 'llama-4-fast',\n models: [{id: 'llama-4-fast', label: 'Llama 4 Fast'}],\n }),\n providerEntry({\n id: 'deepseek',\n label: 'DeepSeek',\n default_model: 'deepseek-coder',\n models: [{id: 'deepseek-coder', label: 'DeepSeek Coder'}],\n }),\n providerEntry({\n id: 'moonshotai',\n label: 'Moonshot AI',\n default_model: 'kimi-k2',\n models: [{id: 'kimi-k2', label: 'Kimi K2'}],\n }),\n providerEntry({\n id: 'azure-openai-responses',\n label: 'Azure OpenAI Responses',\n default_model: 'gpt-5.5-pro',\n models: [{id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'}],\n }),\n providerEntry({\n id: 'amazon-bedrock',\n label: 'Amazon Bedrock',\n support_status: 'unsupported',\n credential_fields: [],\n unsupported_reason: 'AWS cloud credentials are not supported yet.',\n models: [],\n }),\n];\n\nfunction ModelProvidersStory({scenario}: ModelProvidersStoryProps) {\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: fetchForScenario(scenario),\n });\n\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"mx-auto w-full max-w-[760px] bg-background-subtle-base p-24\">\n <WorkspaceModelProvidersSection workspaceId={WORKSPACE_ID} />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderSettings',\n component: ModelProvidersStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'mixed'},\n} satisfies Meta<typeof ModelProvidersStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const ManagedOnly: Story = {\n args: {scenario: 'managed-only'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await canvas.findByText('Managed by this instance. No workspace credentials are required.');\n await canvas.findByRole('button', {name: 'Use in a workflow'});\n },\n};\n\nexport const EmptyConfigured: Story = {\n args: {scenario: 'empty-configured'},\n};\n\nexport const AllConfigured: Story = {\n args: {scenario: 'all-configured'},\n};\n\nexport const CustomConfigured: Story = {\n args: {scenario: 'custom-configured'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ConfigsError: Story = {\n args: {scenario: 'configs-error'},\n};\n\nexport const CatalogError: Story = {\n args: {scenario: 'catalog-error'},\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n};\n\nexport const FilteredAvailableProviders: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.type(\n await canvas.findByRole('searchbox', {name: 'Search providers'}),\n 'openrouter',\n );\n await canvas.findByRole('button', {name: 'Configure OpenRouter'});\n },\n};\n\nexport const NoMatchingAvailableProviders: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.type(\n await canvas.findByRole('searchbox', {name: 'Search providers'}),\n 'not-a-provider',\n );\n await canvas.findByRole('button', {name: 'Clear search'});\n },\n};\n\nexport const ConfigureModalOpen: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure Anthropic'}));\n await screen.findByLabelText('API key');\n },\n};\n\nexport const CustomProviderModalOpen: Story = {\n args: {scenario: 'empty-configured'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure custom provider'}));\n await screen.findByRole('dialog', {name: 'Add custom provider'});\n },\n};\n\nexport const WorkflowExampleModalOpen: Story = {\n args: {scenario: 'mixed'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(\n await canvas.findByRole('button', {name: 'Open Anthropic provider actions'}),\n );\n await userEvent.click(await screen.findByRole('menuitem', {name: 'View workflow example'}));\n await screen.findByRole('dialog', {name: 'Use Anthropic in a workflow'});\n },\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input) => {\n const url = requestUrl(input);\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (url.pathname.endsWith('/agent/model-provider-catalog')) {\n if (scenario === 'catalog-error') return Promise.resolve(errorResponse());\n return Promise.resolve(\n jsonResponse({\n providers: catalogForScenario(scenario),\n ...(scenario === 'managed-only' ? {workspace_providers: 'disabled'} : {}),\n }),\n );\n }\n if (url.pathname.endsWith('/agent/model-providers')) {\n if (scenario === 'configs-error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse(configsForScenario(scenario)));\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction catalogForScenario(scenario: Scenario): ModelProviderCatalogEntryDto[] {\n if (scenario === 'managed-only') {\n return [\n providerEntry({\n id: 'shipfox',\n label: 'Shipfox Managed',\n default_model: 'claude-opus-4-8',\n credential_fields: [],\n models: [\n {id: 'claude-opus-4-8', label: 'Claude Opus 4.8', api: 'anthropic-messages'},\n {id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro', api: 'openai-responses'},\n ],\n }),\n ];\n }\n if (scenario !== 'long-names') return CATALOG;\n return [\n providerEntry({\n id: 'anthropic',\n label: 'Anthropic Enterprise Production Claude Provider With Long Label',\n default_model: 'claude-opus-4-8',\n }),\n providerEntry({\n id: 'openai',\n label: 'OpenAI Platform Shared Workspace Credentials With Long Label',\n default_model: 'gpt-5.5-pro',\n models: [{id: 'gpt-5.5-pro', label: 'GPT-5.5 Pro'}],\n }),\n ];\n}\n\nfunction configsForScenario(scenario: Scenario) {\n if (scenario === 'managed-only') {\n return {configs: [], default_provider_id: null, default_harness_id: null};\n }\n if (scenario === 'empty-configured' || scenario === 'configs-error') {\n return {configs: [], default_provider_id: null, default_harness_id: null};\n }\n if (scenario === 'all-configured') {\n return {\n configs: CATALOG.filter((entry) => entry.support_status === 'supported').map((entry) =>\n providerConfig({\n provider_id: entry.id as SupportedModelProviderId,\n }),\n ),\n default_provider_id: 'anthropic',\n default_harness_id: null,\n };\n }\n if (scenario === 'custom-configured') {\n return {\n configs: [providerConfig({provider_id: 'anthropic'}), customProviderConfig()],\n default_provider_id: 'local-vllm',\n default_harness_id: null,\n };\n }\n return {\n configs: [providerConfig({provider_id: 'anthropic'})],\n default_provider_id: 'anthropic',\n default_harness_id: null,\n };\n}\n\nfunction customProviderConfig(): CustomModelProviderConfigDto {\n return {\n kind: 'custom',\n provider_id: 'local-vllm',\n display_name: 'Local vLLM',\n api: 'openai-completions',\n base_url: 'http://localhost:8000/v1',\n headers: [{name: 'x-region', value: 'us'}],\n secret_header_names: ['authorization'],\n models: [\n {id: 'llama-3.1', label: 'Llama 3.1'},\n {id: 'qwen-coder', label: 'Qwen Coder'},\n ],\n default_model: 'llama-3.1',\n created_at: '2026-05-08T00:00:00.000Z',\n updated_at: '2026-05-08T00:00:00.000Z',\n };\n}\n\nfunction providerEntry(\n overrides: Partial<ModelProviderCatalogEntryDto> = {},\n): ModelProviderCatalogEntryDto {\n return {\n id: 'anthropic',\n label: 'Anthropic',\n support_status: 'supported',\n default_model: null,\n credential_fields: [{key: 'api_key', label: 'API key', secret: true}],\n unsupported_reason: null,\n models: [{id: 'claude-opus-4-8', label: 'Claude Opus 4.8'}],\n ...overrides,\n };\n}\n\nfunction providerConfig(\n overrides: Partial<Omit<ModelProviderConfigDto, 'kind'>> = {},\n): ModelProviderConfigDto {\n return {\n kind: 'builtin',\n provider_id: 'anthropic',\n default_model: null,\n created_at: '2026-05-08T00:00:00.000Z',\n updated_at: '2026-05-08T00:00:00.000Z',\n ...overrides,\n };\n}\n\nfunction requestUrl(input: RequestInfo | URL): URL {\n if (typeof input === 'string') return new URL(input);\n if (input instanceof URL) return input;\n return new URL(input.url);\n}\n\nfunction jsonResponse(body: unknown, init: ResponseInit = {}) {\n return new Response(JSON.stringify(body), {\n status: 200,\n headers: {'content-type': 'application/json'},\n ...init,\n });\n}\n\nfunction errorResponse() {\n return jsonResponse({code: 'server-error'}, {status: 500, statusText: 'Server error'});\n}\n"],"names":["configureApiClient","Toaster","QueryClient","QueryClientProvider","useMemo","screen","userEvent","within","WorkspaceModelProvidersSection","WORKSPACE_ID","CATALOG","providerEntry","id","label","default_model","models","support_status","credential_fields","unsupported_reason","ModelProvidersStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","meta","title","component","parameters","layout","args","Playground","ManagedOnly","play","canvasElement","canvas","findByText","findByRole","name","EmptyConfigured","AllConfigured","CustomConfigured","Loading","ConfigsError","CatalogError","LongNames","FilteredAvailableProviders","type","NoMatchingAvailableProviders","ConfigureModalOpen","click","findByLabelText","CustomProviderModalOpen","WorkflowExampleModalOpen","input","url","requestUrl","Promise","undefined","pathname","endsWith","resolve","errorResponse","jsonResponse","providers","catalogForScenario","workspace_providers","configsForScenario","status","api","configs","default_provider_id","default_harness_id","filter","entry","map","providerConfig","provider_id","customProviderConfig","kind","display_name","base_url","headers","value","secret_header_names","created_at","updated_at","overrides","key","secret","URL","body","init","Response","JSON","stringify","code","statusText"],"mappings":"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"}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import type { HarnessDescriptor, HarnessId, ProviderConfig } from './models.js';
|
|
1
|
+
import type { AgentModel, HarnessDescriptor, HarnessId, ProviderConfig } from './models.js';
|
|
2
2
|
export declare const DEFAULT_HARNESS: HarnessId;
|
|
3
3
|
export declare function listHarnesses(): readonly HarnessDescriptor[];
|
|
4
4
|
export declare function getHarness(id: HarnessId): HarnessDescriptor;
|
|
5
5
|
export declare function harnessSupportsProvider(harnessId: HarnessId, providerId: string): boolean;
|
|
6
6
|
export declare function configSupportsHarness(config: ProviderConfig, harness: HarnessDescriptor): boolean;
|
|
7
|
-
export declare function
|
|
7
|
+
export declare function managedModelSupportsHarness(harnessId: HarnessId, model: Pick<AgentModel, 'api'>): boolean;
|
|
8
|
+
export declare function compatibleHarnessIds({ isCustom, isManaged, models, providerId, }: {
|
|
8
9
|
isCustom: boolean;
|
|
10
|
+
isManaged?: boolean;
|
|
11
|
+
models?: readonly Pick<AgentModel, 'api'>[];
|
|
9
12
|
providerId: string;
|
|
10
13
|
}): HarnessId[];
|
|
11
14
|
//# sourceMappingURL=harness-policy.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness-policy.d.ts","sourceRoot":"","sources":["../../src/core/harness-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"harness-policy.d.ts","sourceRoot":"","sources":["../../src/core/harness-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAC,UAAU,EAAE,iBAAiB,EAAE,SAAS,EAAE,cAAc,EAAC,MAAM,aAAa,CAAC;AAE1F,eAAO,MAAM,eAAe,EAAE,SAAgB,CAAC;AAmD/C,wBAAgB,aAAa,IAAI,SAAS,iBAAiB,EAAE,CAE5D;AAED,wBAAgB,UAAU,CAAC,EAAE,EAAE,SAAS,GAAG,iBAAiB,CAI3D;AAED,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAEzF;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAIjG;AAED,wBAAgB,2BAA2B,CACzC,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,GAC7B,OAAO,CAET;AAED,wBAAgB,oBAAoB,CAAC,EACnC,QAAQ,EACR,SAAiB,EACjB,MAAM,EACN,UAAU,GACX,EAAE;IACD,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,SAAS,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,SAAS,EAAE,CAcd"}
|
|
@@ -63,10 +63,16 @@ export function harnessSupportsProvider(harnessId, providerId) {
|
|
|
63
63
|
export function configSupportsHarness(config, harness) {
|
|
64
64
|
return config.kind === 'custom' ? harness.id === DEFAULT_HARNESS : harness.supportedProviderIds.includes(config.providerId);
|
|
65
65
|
}
|
|
66
|
-
export function
|
|
66
|
+
export function managedModelSupportsHarness(harnessId, model) {
|
|
67
|
+
return harnessId === 'pi' || model.api === undefined || model.api === 'anthropic-messages';
|
|
68
|
+
}
|
|
69
|
+
export function compatibleHarnessIds({ isCustom, isManaged = false, models, providerId }) {
|
|
67
70
|
if (isCustom) return [
|
|
68
71
|
DEFAULT_HARNESS
|
|
69
72
|
];
|
|
73
|
+
if (isManaged) {
|
|
74
|
+
return harnesses.filter((harness)=>models === undefined || models.some((model)=>managedModelSupportsHarness(harness.id, model))).map((harness)=>harness.id);
|
|
75
|
+
}
|
|
70
76
|
return harnesses.filter((harness)=>harness.supportedProviderIds.includes(providerId)).map((harness)=>harness.id);
|
|
71
77
|
}
|
|
72
78
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/harness-policy.ts"],"sourcesContent":["import type {HarnessDescriptor, HarnessId, ProviderConfig} from './models.js';\n\nexport const DEFAULT_HARNESS: HarnessId = 'pi';\n\nconst harnesses: readonly HarnessDescriptor[] = [\n {\n id: 'pi',\n label: 'pi',\n description: 'Works with 30+ model providers',\n supportedProviderIds: [\n 'anthropic',\n 'ant-ling',\n 'azure-openai-responses',\n 'openai',\n 'deepseek',\n 'nvidia',\n 'google',\n 'mistral',\n 'groq',\n 'cerebras',\n 'cloudflare-ai-gateway',\n 'cloudflare-workers-ai',\n 'xai',\n 'openrouter',\n 'vercel-ai-gateway',\n 'zai',\n 'zai-coding-cn',\n 'opencode',\n 'opencode-go',\n 'huggingface',\n 'fireworks',\n 'together',\n 'kimi-coding',\n 'qwen-token-plan',\n 'qwen-token-plan-cn',\n 'minimax',\n 'minimax-cn',\n 'moonshotai',\n 'moonshotai-cn',\n 'xiaomi',\n 'xiaomi-token-plan-cn',\n 'xiaomi-token-plan-ams',\n 'xiaomi-token-plan-sgp',\n ],\n },\n {\n id: 'claude',\n label: 'Claude',\n description: 'Runs on your Anthropic API key',\n supportedProviderIds: ['anthropic'],\n },\n];\n\nexport function listHarnesses(): readonly HarnessDescriptor[] {\n return harnesses;\n}\n\nexport function getHarness(id: HarnessId): HarnessDescriptor {\n const harness = harnesses.find((item) => item.id === id);\n if (harness === undefined) throw new Error(`Unknown harness: ${id}`);\n return harness;\n}\n\nexport function harnessSupportsProvider(harnessId: HarnessId, providerId: string): boolean {\n return getHarness(harnessId).supportedProviderIds.includes(providerId);\n}\n\nexport function configSupportsHarness(config: ProviderConfig, harness: HarnessDescriptor): boolean {\n return config.kind === 'custom'\n ? harness.id === DEFAULT_HARNESS\n : harness.supportedProviderIds.includes(config.providerId);\n}\n\nexport function compatibleHarnessIds({\n isCustom,\n providerId,\n}: {\n isCustom: boolean;\n providerId: string;\n}): HarnessId[] {\n if (isCustom) return [DEFAULT_HARNESS];\n return harnesses\n .filter((harness) => harness.supportedProviderIds.includes(providerId))\n .map((harness) => harness.id);\n}\n"],"names":["DEFAULT_HARNESS","harnesses","id","label","description","supportedProviderIds","listHarnesses","getHarness","harness","find","item","undefined","Error","harnessSupportsProvider","harnessId","providerId","includes","configSupportsHarness","config","kind","compatibleHarnessIds","isCustom","filter","map"],"mappings":"AAEA,OAAO,MAAMA,kBAA6B,KAAK;AAE/C,MAAMC,YAA0C;IAC9C;QACEC,IAAI;QACJC,OAAO;QACPC,aAAa;QACbC,sBAAsB;YACpB;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;IACH;IACA;QACEH,IAAI;QACJC,OAAO;QACPC,aAAa;QACbC,sBAAsB;YAAC;SAAY;IACrC;CACD;AAED,OAAO,SAASC;IACd,OAAOL;AACT;AAEA,OAAO,SAASM,WAAWL,EAAa;IACtC,MAAMM,UAAUP,UAAUQ,IAAI,CAAC,CAACC,OAASA,KAAKR,EAAE,KAAKA;IACrD,IAAIM,YAAYG,WAAW,MAAM,IAAIC,MAAM,CAAC,iBAAiB,EAAEV,IAAI;IACnE,OAAOM;AACT;AAEA,OAAO,SAASK,wBAAwBC,SAAoB,EAAEC,UAAkB;IAC9E,OAAOR,WAAWO,WAAWT,oBAAoB,CAACW,QAAQ,CAACD;AAC7D;AAEA,OAAO,SAASE,sBAAsBC,MAAsB,EAAEV,OAA0B;IACtF,OAAOU,OAAOC,IAAI,KAAK,WACnBX,QAAQN,EAAE,KAAKF,kBACfQ,QAAQH,oBAAoB,CAACW,QAAQ,CAACE,OAAOH,UAAU;AAC7D;AAEA,OAAO,SAASK,qBAAqB,EACnCC,QAAQ,
|
|
1
|
+
{"version":3,"sources":["../../src/core/harness-policy.ts"],"sourcesContent":["import type {AgentModel, HarnessDescriptor, HarnessId, ProviderConfig} from './models.js';\n\nexport const DEFAULT_HARNESS: HarnessId = 'pi';\n\nconst harnesses: readonly HarnessDescriptor[] = [\n {\n id: 'pi',\n label: 'pi',\n description: 'Works with 30+ model providers',\n supportedProviderIds: [\n 'anthropic',\n 'ant-ling',\n 'azure-openai-responses',\n 'openai',\n 'deepseek',\n 'nvidia',\n 'google',\n 'mistral',\n 'groq',\n 'cerebras',\n 'cloudflare-ai-gateway',\n 'cloudflare-workers-ai',\n 'xai',\n 'openrouter',\n 'vercel-ai-gateway',\n 'zai',\n 'zai-coding-cn',\n 'opencode',\n 'opencode-go',\n 'huggingface',\n 'fireworks',\n 'together',\n 'kimi-coding',\n 'qwen-token-plan',\n 'qwen-token-plan-cn',\n 'minimax',\n 'minimax-cn',\n 'moonshotai',\n 'moonshotai-cn',\n 'xiaomi',\n 'xiaomi-token-plan-cn',\n 'xiaomi-token-plan-ams',\n 'xiaomi-token-plan-sgp',\n ],\n },\n {\n id: 'claude',\n label: 'Claude',\n description: 'Runs on your Anthropic API key',\n supportedProviderIds: ['anthropic'],\n },\n];\n\nexport function listHarnesses(): readonly HarnessDescriptor[] {\n return harnesses;\n}\n\nexport function getHarness(id: HarnessId): HarnessDescriptor {\n const harness = harnesses.find((item) => item.id === id);\n if (harness === undefined) throw new Error(`Unknown harness: ${id}`);\n return harness;\n}\n\nexport function harnessSupportsProvider(harnessId: HarnessId, providerId: string): boolean {\n return getHarness(harnessId).supportedProviderIds.includes(providerId);\n}\n\nexport function configSupportsHarness(config: ProviderConfig, harness: HarnessDescriptor): boolean {\n return config.kind === 'custom'\n ? harness.id === DEFAULT_HARNESS\n : harness.supportedProviderIds.includes(config.providerId);\n}\n\nexport function managedModelSupportsHarness(\n harnessId: HarnessId,\n model: Pick<AgentModel, 'api'>,\n): boolean {\n return harnessId === 'pi' || model.api === undefined || model.api === 'anthropic-messages';\n}\n\nexport function compatibleHarnessIds({\n isCustom,\n isManaged = false,\n models,\n providerId,\n}: {\n isCustom: boolean;\n isManaged?: boolean;\n models?: readonly Pick<AgentModel, 'api'>[];\n providerId: string;\n}): HarnessId[] {\n if (isCustom) return [DEFAULT_HARNESS];\n if (isManaged) {\n return harnesses\n .filter(\n (harness) =>\n models === undefined ||\n models.some((model) => managedModelSupportsHarness(harness.id, model)),\n )\n .map((harness) => harness.id);\n }\n return harnesses\n .filter((harness) => harness.supportedProviderIds.includes(providerId))\n .map((harness) => harness.id);\n}\n"],"names":["DEFAULT_HARNESS","harnesses","id","label","description","supportedProviderIds","listHarnesses","getHarness","harness","find","item","undefined","Error","harnessSupportsProvider","harnessId","providerId","includes","configSupportsHarness","config","kind","managedModelSupportsHarness","model","api","compatibleHarnessIds","isCustom","isManaged","models","filter","some","map"],"mappings":"AAEA,OAAO,MAAMA,kBAA6B,KAAK;AAE/C,MAAMC,YAA0C;IAC9C;QACEC,IAAI;QACJC,OAAO;QACPC,aAAa;QACbC,sBAAsB;YACpB;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;YACA;SACD;IACH;IACA;QACEH,IAAI;QACJC,OAAO;QACPC,aAAa;QACbC,sBAAsB;YAAC;SAAY;IACrC;CACD;AAED,OAAO,SAASC;IACd,OAAOL;AACT;AAEA,OAAO,SAASM,WAAWL,EAAa;IACtC,MAAMM,UAAUP,UAAUQ,IAAI,CAAC,CAACC,OAASA,KAAKR,EAAE,KAAKA;IACrD,IAAIM,YAAYG,WAAW,MAAM,IAAIC,MAAM,CAAC,iBAAiB,EAAEV,IAAI;IACnE,OAAOM;AACT;AAEA,OAAO,SAASK,wBAAwBC,SAAoB,EAAEC,UAAkB;IAC9E,OAAOR,WAAWO,WAAWT,oBAAoB,CAACW,QAAQ,CAACD;AAC7D;AAEA,OAAO,SAASE,sBAAsBC,MAAsB,EAAEV,OAA0B;IACtF,OAAOU,OAAOC,IAAI,KAAK,WACnBX,QAAQN,EAAE,KAAKF,kBACfQ,QAAQH,oBAAoB,CAACW,QAAQ,CAACE,OAAOH,UAAU;AAC7D;AAEA,OAAO,SAASK,4BACdN,SAAoB,EACpBO,KAA8B;IAE9B,OAAOP,cAAc,QAAQO,MAAMC,GAAG,KAAKX,aAAaU,MAAMC,GAAG,KAAK;AACxE;AAEA,OAAO,SAASC,qBAAqB,EACnCC,QAAQ,EACRC,YAAY,KAAK,EACjBC,MAAM,EACNX,UAAU,EAMX;IACC,IAAIS,UAAU,OAAO;QAACxB;KAAgB;IACtC,IAAIyB,WAAW;QACb,OAAOxB,UACJ0B,MAAM,CACL,CAACnB,UACCkB,WAAWf,aACXe,OAAOE,IAAI,CAAC,CAACP,QAAUD,4BAA4BZ,QAAQN,EAAE,EAAEmB,SAElEQ,GAAG,CAAC,CAACrB,UAAYA,QAAQN,EAAE;IAChC;IACA,OAAOD,UACJ0B,MAAM,CAAC,CAACnB,UAAYA,QAAQH,oBAAoB,CAACW,QAAQ,CAACD,aAC1Dc,GAAG,CAAC,CAACrB,UAAYA,QAAQN,EAAE;AAChC"}
|
package/dist/core/models.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type HarnessId = 'pi' | 'claude';
|
|
2
|
+
export type WorkspaceProvidersPolicy = 'enabled' | 'disabled';
|
|
2
3
|
export type ProviderApi = 'openai-completions' | 'openai-responses' | 'anthropic-messages' | 'google-generative-ai';
|
|
3
4
|
export interface HarnessDescriptor {
|
|
4
5
|
readonly id: HarnessId;
|
|
@@ -9,6 +10,7 @@ export interface HarnessDescriptor {
|
|
|
9
10
|
export interface AgentModel {
|
|
10
11
|
readonly id: string;
|
|
11
12
|
readonly label: string;
|
|
13
|
+
readonly api?: ProviderApi | undefined;
|
|
12
14
|
readonly contextWindow?: number | undefined;
|
|
13
15
|
readonly maxOutputTokens?: number | undefined;
|
|
14
16
|
readonly inputImage?: boolean | undefined;
|
|
@@ -61,6 +63,7 @@ export interface CustomProviderConfig {
|
|
|
61
63
|
export type ProviderConfig = BuiltinProviderConfig | CustomProviderConfig;
|
|
62
64
|
export interface ProviderCatalog {
|
|
63
65
|
readonly providers: readonly ProviderCatalogEntry[];
|
|
66
|
+
readonly workspaceProviders: WorkspaceProvidersPolicy;
|
|
64
67
|
}
|
|
65
68
|
export interface ProviderConfiguration {
|
|
66
69
|
readonly configs: readonly ProviderConfig[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/core/models.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/core/models.ts"],"names":[],"mappings":"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"}
|
package/dist/core/models.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/core/models.ts"],"sourcesContent":["export type HarnessId = 'pi' | 'claude';\nexport type ProviderApi =\n | 'openai-completions'\n | 'openai-responses'\n | 'anthropic-messages'\n | 'google-generative-ai';\n\nexport interface HarnessDescriptor {\n readonly id: HarnessId;\n readonly label: string;\n readonly description: string;\n readonly supportedProviderIds: readonly string[];\n}\n\nexport interface AgentModel {\n readonly id: string;\n readonly label: string;\n readonly contextWindow?: number | undefined;\n readonly maxOutputTokens?: number | undefined;\n readonly inputImage?: boolean | undefined;\n readonly reasoning?: boolean | undefined;\n}\n\nexport interface CredentialField {\n readonly key: string;\n readonly label: string;\n readonly secret: boolean;\n}\n\nexport interface SupportedProvider {\n readonly kind: 'supported';\n readonly id: string;\n readonly label: string;\n readonly defaultModel: string | null;\n readonly credentialFields: readonly CredentialField[];\n readonly models: readonly AgentModel[];\n}\n\nexport interface UnsupportedProvider {\n readonly kind: 'unsupported';\n readonly id: string;\n readonly label: string;\n readonly unsupportedReason: string;\n}\n\nexport type ProviderCatalogEntry = SupportedProvider | UnsupportedProvider;\n\nexport interface BuiltinProviderConfig {\n readonly kind: 'builtin';\n readonly providerId: string;\n readonly defaultModel: string | null;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface ProviderHeader {\n readonly name: string;\n readonly value: string;\n}\n\nexport interface CustomProviderConfig {\n readonly kind: 'custom';\n readonly providerId: string;\n readonly displayName: string;\n readonly api: ProviderApi;\n readonly baseUrl: string;\n readonly headers: readonly ProviderHeader[];\n readonly secretHeaderNames: readonly string[];\n readonly models: readonly AgentModel[];\n readonly defaultModel: string | null;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport type ProviderConfig = BuiltinProviderConfig | CustomProviderConfig;\n\nexport interface ProviderCatalog {\n readonly providers: readonly ProviderCatalogEntry[];\n}\n\nexport interface ProviderConfiguration {\n readonly configs: readonly ProviderConfig[];\n readonly defaultHarnessId: HarnessId | null;\n readonly defaultProviderId: string | null;\n}\n\nexport interface DefaultModelProviderSelection {\n readonly defaultProviderId: string | null;\n}\n\nexport interface DefaultHarnessSelection {\n readonly defaultHarnessId: HarnessId;\n}\n\nexport interface ProviderCredentialsCommand {\n defaultModel?: string | null | undefined;\n credentials: Record<string, string>;\n setAsDefault?: boolean | undefined;\n}\n\nexport interface CustomProviderHeaderCommand {\n name: string;\n value?: string | undefined;\n secret: boolean;\n keep?: boolean | undefined;\n}\n\nexport interface CustomProviderModelCommand {\n id: string;\n label: string;\n contextWindow?: number | undefined;\n maxOutputTokens?: number | undefined;\n inputImage?: boolean | undefined;\n reasoning?: boolean | undefined;\n}\n\nexport interface CreateCustomProviderCommand {\n slug: string;\n displayName: string;\n api: ProviderApi;\n baseUrl: string;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n models: CustomProviderModelCommand[];\n defaultModel?: string | null | undefined;\n}\n\nexport interface UpdateCustomProviderCommand {\n displayName?: string | undefined;\n api?: ProviderApi | undefined;\n baseUrl?: string | undefined;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n models?: CustomProviderModelCommand[] | undefined;\n defaultModel?: string | null | undefined;\n}\n\nexport interface DiscoverProviderModelsCommand {\n api?: ProviderApi | undefined;\n baseUrl?: string | undefined;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/core/models.ts"],"sourcesContent":["export type HarnessId = 'pi' | 'claude';\nexport type WorkspaceProvidersPolicy = 'enabled' | 'disabled';\nexport type ProviderApi =\n | 'openai-completions'\n | 'openai-responses'\n | 'anthropic-messages'\n | 'google-generative-ai';\n\nexport interface HarnessDescriptor {\n readonly id: HarnessId;\n readonly label: string;\n readonly description: string;\n readonly supportedProviderIds: readonly string[];\n}\n\nexport interface AgentModel {\n readonly id: string;\n readonly label: string;\n readonly api?: ProviderApi | undefined;\n readonly contextWindow?: number | undefined;\n readonly maxOutputTokens?: number | undefined;\n readonly inputImage?: boolean | undefined;\n readonly reasoning?: boolean | undefined;\n}\n\nexport interface CredentialField {\n readonly key: string;\n readonly label: string;\n readonly secret: boolean;\n}\n\nexport interface SupportedProvider {\n readonly kind: 'supported';\n readonly id: string;\n readonly label: string;\n readonly defaultModel: string | null;\n readonly credentialFields: readonly CredentialField[];\n readonly models: readonly AgentModel[];\n}\n\nexport interface UnsupportedProvider {\n readonly kind: 'unsupported';\n readonly id: string;\n readonly label: string;\n readonly unsupportedReason: string;\n}\n\nexport type ProviderCatalogEntry = SupportedProvider | UnsupportedProvider;\n\nexport interface BuiltinProviderConfig {\n readonly kind: 'builtin';\n readonly providerId: string;\n readonly defaultModel: string | null;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport interface ProviderHeader {\n readonly name: string;\n readonly value: string;\n}\n\nexport interface CustomProviderConfig {\n readonly kind: 'custom';\n readonly providerId: string;\n readonly displayName: string;\n readonly api: ProviderApi;\n readonly baseUrl: string;\n readonly headers: readonly ProviderHeader[];\n readonly secretHeaderNames: readonly string[];\n readonly models: readonly AgentModel[];\n readonly defaultModel: string | null;\n readonly createdAt: string;\n readonly updatedAt: string;\n}\n\nexport type ProviderConfig = BuiltinProviderConfig | CustomProviderConfig;\n\nexport interface ProviderCatalog {\n readonly providers: readonly ProviderCatalogEntry[];\n readonly workspaceProviders: WorkspaceProvidersPolicy;\n}\n\nexport interface ProviderConfiguration {\n readonly configs: readonly ProviderConfig[];\n readonly defaultHarnessId: HarnessId | null;\n readonly defaultProviderId: string | null;\n}\n\nexport interface DefaultModelProviderSelection {\n readonly defaultProviderId: string | null;\n}\n\nexport interface DefaultHarnessSelection {\n readonly defaultHarnessId: HarnessId;\n}\n\nexport interface ProviderCredentialsCommand {\n defaultModel?: string | null | undefined;\n credentials: Record<string, string>;\n setAsDefault?: boolean | undefined;\n}\n\nexport interface CustomProviderHeaderCommand {\n name: string;\n value?: string | undefined;\n secret: boolean;\n keep?: boolean | undefined;\n}\n\nexport interface CustomProviderModelCommand {\n id: string;\n label: string;\n contextWindow?: number | undefined;\n maxOutputTokens?: number | undefined;\n inputImage?: boolean | undefined;\n reasoning?: boolean | undefined;\n}\n\nexport interface CreateCustomProviderCommand {\n slug: string;\n displayName: string;\n api: ProviderApi;\n baseUrl: string;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n models: CustomProviderModelCommand[];\n defaultModel?: string | null | undefined;\n}\n\nexport interface UpdateCustomProviderCommand {\n displayName?: string | undefined;\n api?: ProviderApi | undefined;\n baseUrl?: string | undefined;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n models?: CustomProviderModelCommand[] | undefined;\n defaultModel?: string | null | undefined;\n}\n\nexport interface DiscoverProviderModelsCommand {\n api?: ProviderApi | undefined;\n baseUrl?: string | undefined;\n apiKey?: string | undefined;\n headers?: CustomProviderHeaderCommand[] | undefined;\n}\n"],"names":[],"mappings":"AA4IA,WAKC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import type { HarnessDescriptor, ProviderCatalogEntry, ProviderConfig, SupportedProvider } from './models.js';
|
|
1
|
+
import type { HarnessDescriptor, ProviderCatalog, ProviderCatalogEntry, ProviderConfig, SupportedProvider } from './models.js';
|
|
2
2
|
export declare function isSupportedProvider(entry: ProviderCatalogEntry): entry is SupportedProvider;
|
|
3
3
|
export declare function supportsProvider(harness: HarnessDescriptor, providerId: string): boolean;
|
|
4
|
+
export declare function isManagedOnlyCatalog(catalog: ProviderCatalog | undefined): boolean;
|
|
5
|
+
export declare function managedProviderFromCatalog(catalog: ProviderCatalog | undefined): SupportedProvider | undefined;
|
|
4
6
|
export declare function availableProviders(catalog: readonly ProviderCatalogEntry[], configs: readonly ProviderConfig[]): SupportedProvider[];
|
|
5
7
|
export declare function providerMatchesSearch(entry: SupportedProvider, query: string): boolean;
|
|
6
8
|
export declare function customProviderCardMatchesSearch(query: string): boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider-policy.d.ts","sourceRoot":"","sources":["../../src/core/provider-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,KAAK,IAAI,iBAAiB,CAE3F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAExF;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,oBAAoB,EAAE,EACxC,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,iBAAiB,EAAE,CAGrB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAStF;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAItE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM9D;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
|
1
|
+
{"version":3,"file":"provider-policy.d.ts","sourceRoot":"","sources":["../../src/core/provider-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,oBAAoB,GAAG,KAAK,IAAI,iBAAiB,CAE3F;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAExF;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,OAAO,CAElF;AAED,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,eAAe,GAAG,SAAS,GACnC,iBAAiB,GAAG,SAAS,CAG/B;AAED,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,SAAS,oBAAoB,EAAE,EACxC,OAAO,EAAE,SAAS,cAAc,EAAE,GACjC,iBAAiB,EAAE,CAGrB;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAStF;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAItE;AAED,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM9D;AAID,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEzD"}
|
|
@@ -4,6 +4,13 @@ export function isSupportedProvider(entry) {
|
|
|
4
4
|
export function supportsProvider(harness, providerId) {
|
|
5
5
|
return harness.supportedProviderIds.includes(providerId);
|
|
6
6
|
}
|
|
7
|
+
export function isManagedOnlyCatalog(catalog) {
|
|
8
|
+
return catalog?.workspaceProviders === 'disabled';
|
|
9
|
+
}
|
|
10
|
+
export function managedProviderFromCatalog(catalog) {
|
|
11
|
+
if (!isManagedOnlyCatalog(catalog)) return undefined;
|
|
12
|
+
return catalog?.providers.find(isSupportedProvider);
|
|
13
|
+
}
|
|
7
14
|
export function availableProviders(catalog, configs) {
|
|
8
15
|
const configuredIds = new Set(configs.map((config)=>config.providerId));
|
|
9
16
|
return catalog.filter(isSupportedProvider).filter((provider)=>!configuredIds.has(provider.id));
|