@shipfox/client-agent 17.0.0 → 21.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +1 -1
- package/CHANGELOG.md +18 -0
- package/dist/components/custom-model-provider-form.stories.js +1 -1
- package/dist/components/custom-model-provider-form.stories.js.map +1 -1
- package/dist/components/harnesses-section.stories.js +1 -1
- package/dist/components/harnesses-section.stories.js.map +1 -1
- package/dist/components/model-provider-usage-modal.stories.js +1 -1
- package/dist/components/model-provider-usage-modal.stories.js.map +1 -1
- package/dist/components/model-providers-section.stories.js +1 -1
- package/dist/components/model-providers-section.stories.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.js +1 -1
- package/dist/pages/model-provider-onboarding-page.js.map +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js +1 -1
- package/dist/pages/model-provider-onboarding-page.stories.js.map +1 -1
- package/dist/routes/agents-settings.d.ts +3 -0
- package/dist/routes/agents-settings.js +3 -0
- package/dist/routes/agents-settings.js.map +1 -1
- package/dist/routes/model-provider.d.ts +3 -0
- package/dist/routes/model-provider.js +3 -0
- package/dist/routes/model-provider.js.map +1 -1
- package/dist/tsconfig.test.tsbuildinfo +1 -1
- package/package.json +4 -4
- package/src/components/custom-model-provider-form.stories.tsx +1 -1
- package/src/components/harnesses-section.stories.tsx +1 -1
- package/src/components/model-provider-usage-modal.stories.tsx +1 -1
- package/src/components/model-providers-section.stories.tsx +1 -1
- package/src/pages/model-provider-onboarding-page.stories.tsx +1 -1
- package/src/pages/model-provider-onboarding-page.tsx +1 -1
- package/src/routes/agents-settings.tsx +1 -0
- package/src/routes/model-provider.tsx +1 -0
- package/tsconfig.build.tsbuildinfo +1 -1
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
$ shipfox-swc
|
|
2
|
-
Successfully compiled: 37 files with swc (
|
|
2
|
+
Successfully compiled: 37 files with swc (358.51ms)
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# @shipfox/client-agent
|
|
2
2
|
|
|
3
|
+
## 21.0.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [0f4abe4]
|
|
8
|
+
- Updated dependencies [71d0c44]
|
|
9
|
+
- Updated dependencies [9c21429]
|
|
10
|
+
- Updated dependencies [30beb8f]
|
|
11
|
+
- Updated dependencies [16733a7]
|
|
12
|
+
- Updated dependencies [163c40a]
|
|
13
|
+
- Updated dependencies [c4376a1]
|
|
14
|
+
- Updated dependencies [6703982]
|
|
15
|
+
- Updated dependencies [f1d127e]
|
|
16
|
+
- Updated dependencies [0e860d7]
|
|
17
|
+
- @shipfox/react-ui@2.0.0
|
|
18
|
+
- @shipfox/client-shell@21.0.0
|
|
19
|
+
- @shipfox/client-ui@21.0.0
|
|
20
|
+
|
|
3
21
|
## 17.0.0
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
|
@@ -22,7 +22,7 @@ function CustomModelProviderFormStory({ mode }) {
|
|
|
22
22
|
return /*#__PURE__*/ _jsx(QueryClientProvider, {
|
|
23
23
|
client: queryClient,
|
|
24
24
|
children: /*#__PURE__*/ _jsx("div", {
|
|
25
|
-
className: "min-h-screen bg-background-
|
|
25
|
+
className: "min-h-screen bg-background-subtle-base p-24",
|
|
26
26
|
children: /*#__PURE__*/ _jsx(Modal, {
|
|
27
27
|
open: open,
|
|
28
28
|
onOpenChange: setOpen,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/custom-model-provider-form.stories.tsx"],"sourcesContent":["import {configureApiClient} from '@shipfox/client-api';\nimport {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo, useState} from 'react';\nimport type {CustomProviderConfig} from '#core/models.js';\nimport {CustomModelProviderForm} from './custom-model-provider-form.js';\n\ninterface CustomModelProviderFormStoryProps {\n mode: 'create' | 'edit';\n}\n\nfunction CustomModelProviderFormStory({mode}: CustomModelProviderFormStoryProps) {\n const [open, setOpen] = useState(true);\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: () => Promise.resolve(new Response(JSON.stringify({models: []}))),\n });\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"min-h-screen bg-background-
|
|
1
|
+
{"version":3,"sources":["../../src/components/custom-model-provider-form.stories.tsx"],"sourcesContent":["import {configureApiClient} from '@shipfox/client-api';\nimport {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';\nimport type {Meta, StoryObj} from '@storybook/react';\nimport {QueryClient, QueryClientProvider} from '@tanstack/react-query';\nimport {useMemo, useState} from 'react';\nimport type {CustomProviderConfig} from '#core/models.js';\nimport {CustomModelProviderForm} from './custom-model-provider-form.js';\n\ninterface CustomModelProviderFormStoryProps {\n mode: 'create' | 'edit';\n}\n\nfunction CustomModelProviderFormStory({mode}: CustomModelProviderFormStoryProps) {\n const [open, setOpen] = useState(true);\n const queryClient = useMemo(\n () => new QueryClient({defaultOptions: {queries: {retry: false}}}),\n [],\n );\n configureApiClient({\n baseUrl: 'https://api.example.test',\n fetchImpl: () => Promise.resolve(new Response(JSON.stringify({models: []}))),\n });\n\n return (\n <QueryClientProvider client={queryClient}>\n <div className=\"min-h-screen bg-background-subtle-base p-24\">\n <Modal open={open} onOpenChange={setOpen}>\n <ModalContent\n className=\"max-h-[min(760px,calc(100vh-32px))]\"\n aria-describedby={undefined}\n >\n <ModalTitle className=\"sr-only\">\n {mode === 'edit' ? 'Edit custom provider' : 'Add custom provider'}\n </ModalTitle>\n <ModalHeader title={mode === 'edit' ? 'Edit custom provider' : 'Add custom provider'} />\n <CustomModelProviderForm\n workspaceId=\"11111111-1111-4111-8111-111111111111\"\n existingConfig={mode === 'edit' ? customConfig() : undefined}\n onSaved={() => setOpen(false)}\n />\n </ModalContent>\n </Modal>\n </div>\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/CustomProviderForm',\n component: CustomModelProviderFormStory,\n parameters: {layout: 'fullscreen'},\n args: {mode: 'create'},\n} satisfies Meta<typeof CustomModelProviderFormStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const EditStoredSecrets: Story = {\n args: {mode: 'edit'},\n};\n\nfunction customConfig(): CustomProviderConfig {\n return {\n kind: 'custom',\n providerId: 'local-vllm',\n displayName: 'Local vLLM',\n api: 'openai-completions',\n baseUrl: 'http://localhost:8000/v1',\n headers: [{name: 'x-region', value: 'us'}],\n secretHeaderNames: ['authorization'],\n models: [\n {\n id: 'llama-3.1',\n label: 'Llama 3.1',\n contextWindow: 128000,\n maxOutputTokens: 16384,\n },\n {\n id: 'qwen-coder',\n label: 'Qwen Coder',\n contextWindow: 32768,\n maxOutputTokens: 8192,\n },\n ],\n defaultModel: 'llama-3.1',\n createdAt: '2026-05-08T00:00:00.000Z',\n updatedAt: '2026-05-08T00:00:00.000Z',\n };\n}\n"],"names":["configureApiClient","Modal","ModalContent","ModalHeader","ModalTitle","QueryClient","QueryClientProvider","useMemo","useState","CustomModelProviderForm","CustomModelProviderFormStory","mode","open","setOpen","queryClient","defaultOptions","queries","retry","baseUrl","fetchImpl","Promise","resolve","Response","JSON","stringify","models","client","div","className","onOpenChange","aria-describedby","undefined","title","workspaceId","existingConfig","customConfig","onSaved","meta","component","parameters","layout","args","Playground","EditStoredSecrets","kind","providerId","displayName","api","headers","name","value","secretHeaderNames","id","label","contextWindow","maxOutputTokens","defaultModel","createdAt","updatedAt"],"mappings":";AAAA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,KAAK,EAAEC,YAAY,EAAEC,WAAW,EAAEC,UAAU,QAAO,0BAA0B;AAErF,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SAAQC,OAAO,EAAEC,QAAQ,QAAO,QAAQ;AAExC,SAAQC,uBAAuB,QAAO,kCAAkC;AAMxE,SAASC,6BAA6B,EAACC,IAAI,EAAoC;IAC7E,MAAM,CAACC,MAAMC,QAAQ,GAAGL,SAAS;IACjC,MAAMM,cAAcP,QAClB,IAAM,IAAIF,YAAY;YAACU,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAEJjB,mBAAmB;QACjBkB,SAAS;QACTC,WAAW,IAAMC,QAAQC,OAAO,CAAC,IAAIC,SAASC,KAAKC,SAAS,CAAC;gBAACC,QAAQ,EAAE;YAAA;IAC1E;IAEA,qBACE,KAACnB;QAAoBoB,QAAQZ;kBAC3B,cAAA,KAACa;YAAIC,WAAU;sBACb,cAAA,KAAC3B;gBAAMW,MAAMA;gBAAMiB,cAAchB;0BAC/B,cAAA,MAACX;oBACC0B,WAAU;oBACVE,oBAAkBC;;sCAElB,KAAC3B;4BAAWwB,WAAU;sCACnBjB,SAAS,SAAS,yBAAyB;;sCAE9C,KAACR;4BAAY6B,OAAOrB,SAAS,SAAS,yBAAyB;;sCAC/D,KAACF;4BACCwB,aAAY;4BACZC,gBAAgBvB,SAAS,SAASwB,iBAAiBJ;4BACnDK,SAAS,IAAMvB,QAAQ;;;;;;;AAOrC;AAEA,MAAMwB,OAAO;IACXL,OAAO;IACPM,WAAW5B;IACX6B,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAAC9B,MAAM;IAAQ;AACvB;AAEA,eAAe0B,KAAK;AAGpB,OAAO,MAAMK,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,oBAA2B;IACtCF,MAAM;QAAC9B,MAAM;IAAM;AACrB,EAAE;AAEF,SAASwB;IACP,OAAO;QACLS,MAAM;QACNC,YAAY;QACZC,aAAa;QACbC,KAAK;QACL7B,SAAS;QACT8B,SAAS;YAAC;gBAACC,MAAM;gBAAYC,OAAO;YAAI;SAAE;QAC1CC,mBAAmB;YAAC;SAAgB;QACpC1B,QAAQ;YACN;gBACE2B,IAAI;gBACJC,OAAO;gBACPC,eAAe;gBACfC,iBAAiB;YACnB;YACA;gBACEH,IAAI;gBACJC,OAAO;gBACPC,eAAe;gBACfC,iBAAiB;YACnB;SACD;QACDC,cAAc;QACdC,WAAW;QACXC,WAAW;IACb;AACF"}
|
|
@@ -21,7 +21,7 @@ function HarnessesStory({ scenario }) {
|
|
|
21
21
|
client: queryClient,
|
|
22
22
|
children: [
|
|
23
23
|
/*#__PURE__*/ _jsx("div", {
|
|
24
|
-
className: "mx-auto w-full max-w-[760px] bg-background-
|
|
24
|
+
className: "mx-auto w-full max-w-[760px] bg-background-subtle-base p-24",
|
|
25
25
|
children: /*#__PURE__*/ _jsx(WorkspaceHarnessesSection, {
|
|
26
26
|
workspaceId: WORKSPACE_ID
|
|
27
27
|
})
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/harnesses-section.stories.tsx"],"sourcesContent":["import type {ModelProviderConfigDto} 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 {WorkspaceHarnessesSection} from './harnesses-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'default-pi'\n | 'default-claude'\n | 'claude-unavailable'\n | 'default-claude-unavailable'\n | 'loading'\n | 'error';\n\ninterface HarnessesStoryProps {\n scenario: Scenario;\n}\n\nfunction HarnessesStory({scenario}: HarnessesStoryProps) {\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-
|
|
1
|
+
{"version":3,"sources":["../../src/components/harnesses-section.stories.tsx"],"sourcesContent":["import type {ModelProviderConfigDto} 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 {WorkspaceHarnessesSection} from './harnesses-section.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario =\n | 'default-pi'\n | 'default-claude'\n | 'claude-unavailable'\n | 'default-claude-unavailable'\n | 'loading'\n | 'error';\n\ninterface HarnessesStoryProps {\n scenario: Scenario;\n}\n\nfunction HarnessesStory({scenario}: HarnessesStoryProps) {\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 <WorkspaceHarnessesSection workspaceId={WORKSPACE_ID} />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/HarnessSettings',\n component: HarnessesStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'default-pi'},\n} satisfies Meta<typeof HarnessesStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const DefaultClaude: Story = {\n args: {scenario: 'default-claude'},\n};\n\nexport const ClaudeUnavailable: Story = {\n args: {scenario: 'claude-unavailable'},\n};\n\nexport const DefaultClaudeUnavailable: Story = {\n args: {scenario: 'default-claude-unavailable'},\n};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n};\n\nexport const ErrorState: Story = {\n args: {scenario: 'error'},\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return () => {\n if (scenario === 'loading') return new Promise<Response>(() => undefined);\n if (scenario === 'error') return Promise.resolve(errorResponse());\n return Promise.resolve(jsonResponse(configsForScenario(scenario)));\n };\n}\n\nfunction configsForScenario(scenario: Scenario) {\n if (scenario === 'claude-unavailable') {\n return {\n configs: [providerConfig({provider_id: 'openai'})],\n default_provider_id: 'openai',\n default_harness_id: null,\n };\n }\n if (scenario === 'default-claude-unavailable') {\n return {\n configs: [providerConfig({provider_id: 'openai'})],\n default_provider_id: 'openai',\n default_harness_id: 'claude',\n };\n }\n return {\n configs: [providerConfig({provider_id: 'anthropic'})],\n default_provider_id: 'anthropic',\n default_harness_id: scenario === 'default-claude' ? 'claude' : null,\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 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","WorkspaceHarnessesSection","WORKSPACE_ID","HarnessesStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","meta","title","component","parameters","layout","args","Playground","DefaultClaude","ClaudeUnavailable","DefaultClaudeUnavailable","Loading","ErrorState","Promise","undefined","resolve","errorResponse","jsonResponse","configsForScenario","configs","providerConfig","provider_id","default_provider_id","default_harness_id","overrides","kind","default_model","created_at","updated_at","body","init","Response","JSON","stringify","status","headers","code","statusText"],"mappings":";AACA,SAAQA,kBAAkB,QAAO,sBAAsB;AACvD,SAAQC,OAAO,QAAO,0BAA0B;AAEhD,SAAQC,WAAW,EAAEC,mBAAmB,QAAO,wBAAwB;AACvE,SAAQC,OAAO,QAAO,QAAQ;AAC9B,SAAQC,yBAAyB,QAAO,yBAAyB;AAEjE,MAAMC,eAAe;AAcrB,SAASC,eAAe,EAACC,QAAQ,EAAsB;IACrDR,mBAAmB;QACjBS,SAAS;QACTC,WAAWC,iBAAiBH;IAC9B;IAEA,MAAMI,cAAcR,QAClB,IAAM,IAAIF,YAAY;YAACW,gBAAgB;gBAACC,SAAS;oBAACC,OAAO;gBAAK;YAAC;QAAC,IAChE,EAAE;IAGJ,qBACE,MAACZ;QAAoBa,QAAQJ;;0BAC3B,KAACK;gBAAIC,WAAU;0BACb,cAAA,KAACb;oBAA0Bc,aAAab;;;0BAE1C,KAACL;;;AAGP;AAEA,MAAMmB,OAAO;IACXC,OAAO;IACPC,WAAWf;IACXgB,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACjB,UAAU;IAAY;AAC/B;AAEA,eAAeY,KAAK;AAGpB,OAAO,MAAMM,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,gBAAuB;IAClCF,MAAM;QAACjB,UAAU;IAAgB;AACnC,EAAE;AAEF,OAAO,MAAMoB,oBAA2B;IACtCH,MAAM;QAACjB,UAAU;IAAoB;AACvC,EAAE;AAEF,OAAO,MAAMqB,2BAAkC;IAC7CJ,MAAM;QAACjB,UAAU;IAA4B;AAC/C,EAAE;AAEF,OAAO,MAAMsB,UAAiB;IAC5BL,MAAM;QAACjB,UAAU;IAAS;AAC5B,EAAE;AAEF,OAAO,MAAMuB,aAAoB;IAC/BN,MAAM;QAACjB,UAAU;IAAO;AAC1B,EAAE;AAEF,SAASG,iBAAiBH,QAAkB;IAC1C,OAAO;QACL,IAAIA,aAAa,WAAW,OAAO,IAAIwB,QAAkB,IAAMC;QAC/D,IAAIzB,aAAa,SAAS,OAAOwB,QAAQE,OAAO,CAACC;QACjD,OAAOH,QAAQE,OAAO,CAACE,aAAaC,mBAAmB7B;IACzD;AACF;AAEA,SAAS6B,mBAAmB7B,QAAkB;IAC5C,IAAIA,aAAa,sBAAsB;QACrC,OAAO;YACL8B,SAAS;gBAACC,eAAe;oBAACC,aAAa;gBAAQ;aAAG;YAClDC,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,IAAIlC,aAAa,8BAA8B;QAC7C,OAAO;YACL8B,SAAS;gBAACC,eAAe;oBAACC,aAAa;gBAAQ;aAAG;YAClDC,qBAAqB;YACrBC,oBAAoB;QACtB;IACF;IACA,OAAO;QACLJ,SAAS;YAACC,eAAe;gBAACC,aAAa;YAAW;SAAG;QACrDC,qBAAqB;QACrBC,oBAAoBlC,aAAa,mBAAmB,WAAW;IACjE;AACF;AAEA,SAAS+B,eACPI,YAA2D,CAAC,CAAC;IAE7D,OAAO;QACLC,MAAM;QACNJ,aAAa;QACbK,eAAe;QACfC,YAAY;QACZC,YAAY;QACZ,GAAGJ,SAAS;IACd;AACF;AAEA,SAASP,aAAaY,IAAa,EAAEC,OAAqB,CAAC,CAAC;IAC1D,OAAO,IAAIC,SAASC,KAAKC,SAAS,CAACJ,OAAO;QACxCK,QAAQ;QACRC,SAAS;YAAC,gBAAgB;QAAkB;QAC5C,GAAGL,IAAI;IACT;AACF;AAEA,SAASd;IACP,OAAOC,aAAa;QAACmB,MAAM;IAAc,GAAG;QAACF,QAAQ;QAAKG,YAAY;IAAc;AACtF"}
|
|
@@ -7,7 +7,7 @@ function ModelProviderUsageModalStory({ variant }) {
|
|
|
7
7
|
const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();
|
|
8
8
|
const target = variant === 'custom' ? usageTargetFromCustomConfig(customProviderConfig()) : usageTargetFromCatalogEntry(entry);
|
|
9
9
|
return /*#__PURE__*/ _jsx("div", {
|
|
10
|
-
className: "min-h-screen bg-background-
|
|
10
|
+
className: "min-h-screen bg-background-subtle-base p-24",
|
|
11
11
|
children: /*#__PURE__*/ _jsx(ModelProviderUsageModal, {
|
|
12
12
|
target: target,
|
|
13
13
|
initialModel: target.defaultModel,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/model-provider-usage-modal.stories.tsx"],"sourcesContent":["import type {Meta, StoryObj} from '@storybook/react';\nimport {useState} from 'react';\nimport type {CustomProviderConfig, SupportedProvider} from '#core/models.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\n\ninterface ModelProviderUsageModalStoryProps {\n variant: 'anthropic' | 'custom' | 'long-list';\n}\n\nfunction ModelProviderUsageModalStory({variant}: ModelProviderUsageModalStoryProps) {\n const [open, setOpen] = useState(true);\n const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();\n const target =\n variant === 'custom'\n ? usageTargetFromCustomConfig(customProviderConfig())\n : usageTargetFromCatalogEntry(entry);\n\n return (\n <div className=\"min-h-screen bg-background-
|
|
1
|
+
{"version":3,"sources":["../../src/components/model-provider-usage-modal.stories.tsx"],"sourcesContent":["import type {Meta, StoryObj} from '@storybook/react';\nimport {useState} from 'react';\nimport type {CustomProviderConfig, SupportedProvider} from '#core/models.js';\nimport {ModelProviderUsageModal} from './model-provider-usage-modal.js';\nimport {\n usageTargetFromCatalogEntry,\n usageTargetFromCustomConfig,\n} from './model-provider-usage-target.js';\n\ninterface ModelProviderUsageModalStoryProps {\n variant: 'anthropic' | 'custom' | 'long-list';\n}\n\nfunction ModelProviderUsageModalStory({variant}: ModelProviderUsageModalStoryProps) {\n const [open, setOpen] = useState(true);\n const entry = variant === 'long-list' ? longListEntry() : anthropicEntry();\n const target =\n variant === 'custom'\n ? usageTargetFromCustomConfig(customProviderConfig())\n : usageTargetFromCatalogEntry(entry);\n\n return (\n <div className=\"min-h-screen bg-background-subtle-base p-24\">\n <ModelProviderUsageModal\n target={target}\n initialModel={target.defaultModel}\n workspaceDefaultHarnessId=\"claude\"\n open={open}\n onOpenChange={setOpen}\n />\n </div>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderUsageModal',\n component: ModelProviderUsageModalStory,\n parameters: {layout: 'fullscreen'},\n args: {variant: 'anthropic'},\n} satisfies Meta<typeof ModelProviderUsageModalStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const LongModelList: Story = {\n args: {variant: 'long-list'},\n};\n\nexport const CustomProvider: Story = {\n args: {variant: 'custom'},\n};\n\nfunction anthropicEntry(): SupportedProvider {\n return {\n kind: 'supported',\n id: 'anthropic',\n label: 'Anthropic',\n defaultModel: 'claude-opus-4-8',\n credentialFields: [{key: 'api_key', label: 'API key', secret: true}],\n models: [\n {id: 'claude-opus-4-8', label: 'Claude Opus 4.8'},\n {id: 'claude-sonnet-4-8', label: 'Claude Sonnet 4.8'},\n {id: 'claude-haiku-4-5', label: 'Claude Haiku 4.5'},\n ],\n };\n}\n\nfunction longListEntry(): SupportedProvider {\n return {\n kind: 'supported',\n id: 'cloudflare-workers-ai',\n label: 'Cloudflare Workers AI',\n defaultModel: '@cf/moonshotai/kimi-k2.7-code',\n credentialFields: [{key: 'api_token', label: 'API token', secret: true}],\n models: Array.from({length: 56}, (_, index) => ({\n id:\n index === 0\n ? '@cf/moonshotai/kimi-k2.7-code'\n : `provider/research-lab/model-family-${String(index).padStart(2, '0')}-large-context`,\n label: index === 0 ? 'Kimi K2.7 Code' : `Research Model ${index}`,\n })),\n };\n}\n\nfunction customProviderConfig(): CustomProviderConfig {\n return {\n kind: 'custom',\n providerId: 'local-vllm',\n displayName: 'Local vLLM',\n api: 'openai-completions',\n baseUrl: 'http://localhost:8000/v1',\n headers: [],\n secretHeaderNames: [],\n models: [{id: 'llama-3.1', label: 'Llama 3.1'}],\n defaultModel: 'llama-3.1',\n createdAt: '2026-05-08T00:00:00.000Z',\n updatedAt: '2026-05-08T00:00:00.000Z',\n };\n}\n"],"names":["useState","ModelProviderUsageModal","usageTargetFromCatalogEntry","usageTargetFromCustomConfig","ModelProviderUsageModalStory","variant","open","setOpen","entry","longListEntry","anthropicEntry","target","customProviderConfig","div","className","initialModel","defaultModel","workspaceDefaultHarnessId","onOpenChange","meta","title","component","parameters","layout","args","Playground","LongModelList","CustomProvider","kind","id","label","credentialFields","key","secret","models","Array","from","length","_","index","String","padStart","providerId","displayName","api","baseUrl","headers","secretHeaderNames","createdAt","updatedAt"],"mappings":";AACA,SAAQA,QAAQ,QAAO,QAAQ;AAE/B,SAAQC,uBAAuB,QAAO,kCAAkC;AACxE,SACEC,2BAA2B,EAC3BC,2BAA2B,QACtB,mCAAmC;AAM1C,SAASC,6BAA6B,EAACC,OAAO,EAAoC;IAChF,MAAM,CAACC,MAAMC,QAAQ,GAAGP,SAAS;IACjC,MAAMQ,QAAQH,YAAY,cAAcI,kBAAkBC;IAC1D,MAAMC,SACJN,YAAY,WACRF,4BAA4BS,0BAC5BV,4BAA4BM;IAElC,qBACE,KAACK;QAAIC,WAAU;kBACb,cAAA,KAACb;YACCU,QAAQA;YACRI,cAAcJ,OAAOK,YAAY;YACjCC,2BAA0B;YAC1BX,MAAMA;YACNY,cAAcX;;;AAItB;AAEA,MAAMY,OAAO;IACXC,OAAO;IACPC,WAAWjB;IACXkB,YAAY;QAACC,QAAQ;IAAY;IACjCC,MAAM;QAACnB,SAAS;IAAW;AAC7B;AAEA,eAAec,KAAK;AAGpB,OAAO,MAAMM,aAAoB,CAAC,EAAE;AAEpC,OAAO,MAAMC,gBAAuB;IAClCF,MAAM;QAACnB,SAAS;IAAW;AAC7B,EAAE;AAEF,OAAO,MAAMsB,iBAAwB;IACnCH,MAAM;QAACnB,SAAS;IAAQ;AAC1B,EAAE;AAEF,SAASK;IACP,OAAO;QACLkB,MAAM;QACNC,IAAI;QACJC,OAAO;QACPd,cAAc;QACde,kBAAkB;YAAC;gBAACC,KAAK;gBAAWF,OAAO;gBAAWG,QAAQ;YAAI;SAAE;QACpEC,QAAQ;YACN;gBAACL,IAAI;gBAAmBC,OAAO;YAAiB;YAChD;gBAACD,IAAI;gBAAqBC,OAAO;YAAmB;YACpD;gBAACD,IAAI;gBAAoBC,OAAO;YAAkB;SACnD;IACH;AACF;AAEA,SAASrB;IACP,OAAO;QACLmB,MAAM;QACNC,IAAI;QACJC,OAAO;QACPd,cAAc;QACde,kBAAkB;YAAC;gBAACC,KAAK;gBAAaF,OAAO;gBAAaG,QAAQ;YAAI;SAAE;QACxEC,QAAQC,MAAMC,IAAI,CAAC;YAACC,QAAQ;QAAE,GAAG,CAACC,GAAGC,QAAW,CAAA;gBAC9CV,IACEU,UAAU,IACN,kCACA,CAAC,mCAAmC,EAAEC,OAAOD,OAAOE,QAAQ,CAAC,GAAG,KAAK,cAAc,CAAC;gBAC1FX,OAAOS,UAAU,IAAI,mBAAmB,CAAC,eAAe,EAAEA,OAAO;YACnE,CAAA;IACF;AACF;AAEA,SAAS3B;IACP,OAAO;QACLgB,MAAM;QACNc,YAAY;QACZC,aAAa;QACbC,KAAK;QACLC,SAAS;QACTC,SAAS,EAAE;QACXC,mBAAmB,EAAE;QACrBb,QAAQ;YAAC;gBAACL,IAAI;gBAAaC,OAAO;YAAW;SAAE;QAC/Cd,cAAc;QACdgC,WAAW;QACXC,WAAW;IACb;AACF"}
|
|
@@ -150,7 +150,7 @@ function ModelProvidersStory({ scenario }) {
|
|
|
150
150
|
client: queryClient,
|
|
151
151
|
children: [
|
|
152
152
|
/*#__PURE__*/ _jsx("div", {
|
|
153
|
-
className: "mx-auto w-full max-w-[760px] bg-background-
|
|
153
|
+
className: "mx-auto w-full max-w-[760px] bg-background-subtle-base p-24",
|
|
154
154
|
children: /*#__PURE__*/ _jsx(WorkspaceModelProvidersSection, {
|
|
155
155
|
workspaceId: WORKSPACE_ID
|
|
156
156
|
})
|
|
@@ -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-neutral-background 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":"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"}
|
|
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":"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"}
|
|
@@ -79,7 +79,7 @@ export function ModelProviderOnboardingPage({ workspaceId, onSkip, onConfigured
|
|
|
79
79
|
const selectedHarnessDescriptor = onboarding.step === 'choose-harness' ? null : listHarnesses().find((harness)=>harness.id === onboarding.harnessId);
|
|
80
80
|
const headingId = onboarding.step === 'choose-harness' ? 'model-provider-harness-step' : 'model-provider-provider-step';
|
|
81
81
|
return /*#__PURE__*/ _jsxs("div", {
|
|
82
|
-
className: "mx-auto flex w-full
|
|
82
|
+
className: "mx-auto flex w-full flex-col gap-section",
|
|
83
83
|
children: [
|
|
84
84
|
/*#__PURE__*/ _jsxs("header", {
|
|
85
85
|
className: "flex flex-col gap-cluster",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pages/model-provider-onboarding-page.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useEffect, useMemo, useReducer} from 'react';\nimport {AvailableProvidersGrid, PROVIDER_GRID_CLASS} from '#components/available-providers-grid.js';\nimport {modelProviderConfigErrorToFormError} from '#components/form-errors.js';\nimport {ModelProviderTestAndSaveForm} from '#components/test-and-save-form.js';\nimport {DEFAULT_HARNESS, harnessSupportsProvider, listHarnesses} from '#core/harness-policy.js';\nimport type {HarnessDescriptor, HarnessId, SupportedProvider} from '#core/models.js';\nimport {initialOnboardingState, onboardingReducer} from '#core/onboarding-reducer.js';\nimport {isSupportedProvider} from '#core/provider-policy.js';\nimport {\n useModelProviderCatalogQuery,\n useSetDefaultHarnessMutation,\n} from '#hooks/api/model-providers.js';\nimport {dismissModelProviderOnboarding} from '#state/model-provider-onboarding.js';\n\nconst SURFACE_CLASS =\n 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport function ModelProviderOnboardingPage({\n workspaceId,\n onSkip,\n onConfigured,\n}: {\n workspaceId: string;\n onSkip: () => void;\n onConfigured: () => void;\n}) {\n const catalogQuery = useModelProviderCatalogQuery();\n const setDefaultHarness = useSetDefaultHarnessMutation();\n const [onboarding, dispatch] = useReducer(onboardingReducer, initialOnboardingState);\n const supportedProviders = catalogQuery.data?.providers.filter(isSupportedProvider) ?? [];\n const filteredProviders = useMemo(() => {\n if (onboarding.step === 'choose-harness') return [];\n return supportedProviders.filter((provider) =>\n harnessSupportsProvider(onboarding.harnessId, provider.id),\n );\n }, [onboarding, supportedProviders]);\n\n useEffect(() => {\n document\n .getElementById(\n onboarding.step === 'choose-harness'\n ? 'model-provider-harness-step'\n : 'model-provider-provider-step',\n )\n ?.focus();\n }, [onboarding.step]);\n\n function handleSkip() {\n try {\n dismissModelProviderOnboarding(workspaceId);\n } catch {\n // Skip is best-effort persistence; access to the product must not depend on storage.\n }\n onSkip();\n }\n\n async function handleProviderSaved() {\n if (onboarding.step !== 'configure-provider' && onboarding.step !== 'saving-default-harness')\n return;\n\n const provider = onboarding.provider;\n if (onboarding.step === 'configure-provider') dispatch({type: 'provider-saved'});\n if (onboarding.harnessId === DEFAULT_HARNESS) {\n toast.success(`${provider.label} saved`);\n dispatch({type: 'default-harness-saved'});\n onConfigured();\n return;\n }\n\n try {\n await setDefaultHarness.mutateAsync({\n workspaceId,\n harnessId: onboarding.harnessId,\n });\n toast.success(`${provider.label} saved`);\n dispatch({type: 'default-harness-saved'});\n onConfigured();\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n dispatch({\n type: 'default-harness-failed',\n message: mapped.message || 'Could not save default harness. Try again.',\n });\n }\n }\n\n const selectedHarnessDescriptor =\n onboarding.step === 'choose-harness'\n ? null\n : listHarnesses().find((harness) => harness.id === onboarding.harnessId);\n const headingId =\n onboarding.step === 'choose-harness'\n ? 'model-provider-harness-step'\n : 'model-provider-provider-step';\n\n return (\n <div className=\"mx-auto flex w-full max-w-[640px] flex-col gap-section\">\n <header className=\"flex flex-col gap-cluster\">\n <div className=\"flex items-start justify-between gap-group max-[520px]:flex-col max-[520px]:gap-inline\">\n <Header id={headingId} variant=\"h1\" tabIndex={-1} className=\"outline-none\">\n {selectedHarnessDescriptor\n ? `Configure ${selectedHarnessDescriptor.label}`\n : 'Choose agent harness'}\n </Header>\n <Button type=\"button\" variant=\"secondary\" onClick={handleSkip} className=\"shrink-0\">\n Skip for now\n </Button>\n </div>\n <Text size=\"md\" className=\"text-foreground-neutral-muted\">\n {selectedHarnessDescriptor\n ? `${selectedHarnessDescriptor.label} needs a compatible model provider. Add your own API key, or go back to choose a different harness.`\n : 'A harness runs agent steps. Choose the engine you want first, then connect a compatible model provider.'}\n </Text>\n </header>\n\n <section aria-labelledby={headingId} className=\"flex flex-col gap-group\">\n {onboarding.step === 'choose-harness' ? (\n <HarnessPicker\n onSelect={(harnessId) => dispatch({type: 'harness-selected', harnessId})}\n />\n ) : (\n <>\n <div>\n <Button type=\"button\" variant=\"transparent\" onClick={() => dispatch({type: 'back'})}>\n Back\n </Button>\n </div>\n <ModelProviderPicker\n key={onboarding.harnessId}\n catalogQuery={catalogQuery}\n supportedProviders={filteredProviders}\n onSelect={(entry) => {\n dispatch({type: 'provider-selected', provider: entry});\n }}\n />\n </>\n )}\n </section>\n\n <Modal\n open={\n onboarding.step === 'configure-provider' || onboarding.step === 'saving-default-harness'\n }\n onOpenChange={(open) => {\n if (!open && onboarding.step === 'configure-provider') dispatch({type: 'back'});\n }}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness'\n ? `Configure ${onboarding.provider.label}`\n : ''}\n </ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness'\n ? `Configure ${onboarding.provider.label}`\n : ''}\n </Text>\n </ModalHeader>\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness' ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-inline\">\n {onboarding.step === 'saving-default-harness' ? (\n <div role=\"status\" className=\"px-row\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Saving harness default...\n </Text>\n </div>\n ) : null}\n {onboarding.step === 'saving-default-harness' && onboarding.error ? (\n <div className=\"px-row\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex flex-col gap-inline\">\n <Text size=\"sm\" bold>\n Could not save default harness\n </Text>\n <Text size=\"sm\">{onboarding.error}</Text>\n </div>\n </Callout>\n </div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <ModelProviderTestAndSaveForm\n workspaceId={workspaceId}\n entry={onboarding.provider}\n setAsDefaultOnSave\n onSaved={() => {\n void handleProviderSaved();\n }}\n />\n </div>\n </div>\n ) : null}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\nfunction HarnessPicker({onSelect}: {onSelect: (harness: HarnessId) => void}) {\n return (\n <ul className={PROVIDER_GRID_CLASS} aria-label=\"Agent harnesses\">\n {listHarnesses().map((harness) => (\n <HarnessCard key={harness.id} harness={harness} onChoose={() => onSelect(harness.id)} />\n ))}\n </ul>\n );\n}\n\nfunction HarnessCard({harness, onChoose}: {harness: HarnessDescriptor; onChoose: () => void}) {\n return (\n <li>\n <button\n type=\"button\"\n className={cn(\n 'group block w-full cursor-pointer p-panel-compact text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus',\n SURFACE_CLASS,\n )}\n aria-label={`Choose ${harness.label}`}\n onClick={onChoose}\n >\n <div className=\"flex min-w-0 items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"md\" bold className=\"min-w-0 truncate\">\n {harness.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {harness.description}\n </Text>\n </div>\n <div className=\"flex shrink-0 items-center gap-tight text-foreground-neutral-muted transition-colors group-hover:text-foreground-highlight-interactive\">\n <Text size=\"sm\">Choose</Text>\n <Icon name=\"chevronRight\" className=\"size-16\" />\n </div>\n </div>\n </button>\n </li>\n );\n}\n\nfunction ModelProviderPicker({\n catalogQuery,\n supportedProviders,\n onSelect,\n}: {\n catalogQuery: ReturnType<typeof useModelProviderCatalogQuery>;\n supportedProviders: SupportedProvider[];\n onSelect: (entry: SupportedProvider) => void;\n}) {\n if (catalogQuery.isPending) {\n return (\n <div role=\"status\" aria-busy=\"true\" aria-label=\"Loading model providers\">\n <ModelProviderGridSkeleton />\n </div>\n );\n }\n\n if (catalogQuery.isError && catalogQuery.data === undefined) {\n return <QueryLoadError query={catalogQuery} subject=\"model provider catalog\" />;\n }\n\n if (catalogQuery.data !== undefined && supportedProviders.length === 0) {\n return (\n <EmptyState\n icon=\"componentLine\"\n title=\"No providers available to configure\"\n description=\"Skip for now and add one later from workspace settings.\"\n />\n );\n }\n\n return <AvailableProvidersGrid entries={supportedProviders} onSelect={onSelect} />;\n}\n\nfunction ModelProviderGridSkeleton() {\n return (\n <div className={PROVIDER_GRID_CLASS}>\n {[0, 1, 2, 3].map((card) => (\n <Skeleton key={card} className=\"h-136 w-full\" />\n ))}\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Callout","EmptyState","Icon","Modal","ModalContent","ModalHeader","ModalTitle","Skeleton","toast","Header","Text","cn","useEffect","useMemo","useReducer","AvailableProvidersGrid","PROVIDER_GRID_CLASS","modelProviderConfigErrorToFormError","ModelProviderTestAndSaveForm","DEFAULT_HARNESS","harnessSupportsProvider","listHarnesses","initialOnboardingState","onboardingReducer","isSupportedProvider","useModelProviderCatalogQuery","useSetDefaultHarnessMutation","dismissModelProviderOnboarding","SURFACE_CLASS","ModelProviderOnboardingPage","workspaceId","onSkip","onConfigured","catalogQuery","setDefaultHarness","onboarding","dispatch","supportedProviders","data","providers","filter","filteredProviders","step","provider","harnessId","id","document","getElementById","focus","handleSkip","handleProviderSaved","type","success","label","mutateAsync","error","mapped","message","selectedHarnessDescriptor","find","harness","headingId","div","className","header","variant","tabIndex","onClick","size","section","aria-labelledby","HarnessPicker","onSelect","ModelProviderPicker","entry","open","onOpenChange","aria-describedby","undefined","aria-hidden","role","bold","setAsDefaultOnSave","onSaved","ul","aria-label","map","HarnessCard","onChoose","li","button","description","name","isPending","aria-busy","ModelProviderGridSkeleton","isError","query","subject","length","icon","title","entries","card"],"mappings":";AAAA,SAAQA,cAAc,QAAO,qBAAqB;AAClD,SAAQC,MAAM,QAAO,2BAA2B;AAChD,SAAQC,OAAO,QAAO,4BAA4B;AAClD,SAAQC,UAAU,QAAO,gCAAgC;AACzD,SAAQC,IAAI,QAAO,yBAAyB;AAC5C,SAAQC,KAAK,EAAEC,YAAY,EAAEC,WAAW,EAAEC,UAAU,QAAO,0BAA0B;AACrF,SAAQC,QAAQ,QAAO,6BAA6B;AACpD,SAAQC,KAAK,QAAO,0BAA0B;AAC9C,SAAQC,MAAM,EAAEC,IAAI,QAAO,+BAA+B;AAC1D,SAAQC,EAAE,QAAO,0BAA0B;AAC3C,SAAQC,SAAS,EAAEC,OAAO,EAAEC,UAAU,QAAO,QAAQ;AACrD,SAAQC,sBAAsB,EAAEC,mBAAmB,QAAO,0CAA0C;AACpG,SAAQC,mCAAmC,QAAO,6BAA6B;AAC/E,SAAQC,4BAA4B,QAAO,oCAAoC;AAC/E,SAAQC,eAAe,EAAEC,uBAAuB,EAAEC,aAAa,QAAO,0BAA0B;AAEhG,SAAQC,sBAAsB,EAAEC,iBAAiB,QAAO,8BAA8B;AACtF,SAAQC,mBAAmB,QAAO,2BAA2B;AAC7D,SACEC,4BAA4B,EAC5BC,4BAA4B,QACvB,gCAAgC;AACvC,SAAQC,8BAA8B,QAAO,sCAAsC;AAEnF,MAAMC,gBACJ;AAEF,OAAO,SAASC,4BAA4B,EAC1CC,WAAW,EACXC,MAAM,EACNC,YAAY,EAKb;IACC,MAAMC,eAAeR;IACrB,MAAMS,oBAAoBR;IAC1B,MAAM,CAACS,YAAYC,SAAS,GAAGtB,WAAWS,mBAAmBD;IAC7D,MAAMe,qBAAqBJ,aAAaK,IAAI,EAAEC,UAAUC,OAAOhB,wBAAwB,EAAE;IACzF,MAAMiB,oBAAoB5B,QAAQ;QAChC,IAAIsB,WAAWO,IAAI,KAAK,kBAAkB,OAAO,EAAE;QACnD,OAAOL,mBAAmBG,MAAM,CAAC,CAACG,WAChCvB,wBAAwBe,WAAWS,SAAS,EAAED,SAASE,EAAE;IAE7D,GAAG;QAACV;QAAYE;KAAmB;IAEnCzB,UAAU;QACRkC,SACGC,cAAc,CACbZ,WAAWO,IAAI,KAAK,mBAChB,gCACA,iCAEJM;IACN,GAAG;QAACb,WAAWO,IAAI;KAAC;IAEpB,SAASO;QACP,IAAI;YACFtB,+BAA+BG;QACjC,EAAE,OAAM;QACN,qFAAqF;QACvF;QACAC;IACF;IAEA,eAAemB;QACb,IAAIf,WAAWO,IAAI,KAAK,wBAAwBP,WAAWO,IAAI,KAAK,0BAClE;QAEF,MAAMC,WAAWR,WAAWQ,QAAQ;QACpC,IAAIR,WAAWO,IAAI,KAAK,sBAAsBN,SAAS;YAACe,MAAM;QAAgB;QAC9E,IAAIhB,WAAWS,SAAS,KAAKzB,iBAAiB;YAC5CX,MAAM4C,OAAO,CAAC,GAAGT,SAASU,KAAK,CAAC,MAAM,CAAC;YACvCjB,SAAS;gBAACe,MAAM;YAAuB;YACvCnB;YACA;QACF;QAEA,IAAI;YACF,MAAME,kBAAkBoB,WAAW,CAAC;gBAClCxB;gBACAc,WAAWT,WAAWS,SAAS;YACjC;YACApC,MAAM4C,OAAO,CAAC,GAAGT,SAASU,KAAK,CAAC,MAAM,CAAC;YACvCjB,SAAS;gBAACe,MAAM;YAAuB;YACvCnB;QACF,EAAE,OAAOuB,OAAO;YACd,MAAMC,SAASvC,oCAAoCsC;YACnDnB,SAAS;gBACPe,MAAM;gBACNM,SAASD,OAAOC,OAAO,IAAI;YAC7B;QACF;IACF;IAEA,MAAMC,4BACJvB,WAAWO,IAAI,KAAK,mBAChB,OACArB,gBAAgBsC,IAAI,CAAC,CAACC,UAAYA,QAAQf,EAAE,KAAKV,WAAWS,SAAS;IAC3E,MAAMiB,YACJ1B,WAAWO,IAAI,KAAK,mBAChB,gCACA;IAEN,qBACE,MAACoB;QAAIC,WAAU;;0BACb,MAACC;gBAAOD,WAAU;;kCAChB,MAACD;wBAAIC,WAAU;;0CACb,KAACtD;gCAAOoC,IAAIgB;gCAAWI,SAAQ;gCAAKC,UAAU,CAAC;gCAAGH,WAAU;0CACzDL,4BACG,CAAC,UAAU,EAAEA,0BAA0BL,KAAK,EAAE,GAC9C;;0CAEN,KAACtD;gCAAOoD,MAAK;gCAASc,SAAQ;gCAAYE,SAASlB;gCAAYc,WAAU;0CAAW;;;;kCAItF,KAACrD;wBAAK0D,MAAK;wBAAKL,WAAU;kCACvBL,4BACG,GAAGA,0BAA0BL,KAAK,CAAC,mGAAmG,CAAC,GACvI;;;;0BAIR,KAACgB;gBAAQC,mBAAiBT;gBAAWE,WAAU;0BAC5C5B,WAAWO,IAAI,KAAK,iCACnB,KAAC6B;oBACCC,UAAU,CAAC5B,YAAcR,SAAS;4BAACe,MAAM;4BAAoBP;wBAAS;mCAGxE;;sCACE,KAACkB;sCACC,cAAA,KAAC/D;gCAAOoD,MAAK;gCAASc,SAAQ;gCAAcE,SAAS,IAAM/B,SAAS;wCAACe,MAAM;oCAAM;0CAAI;;;sCAIvF,KAACsB;4BAECxC,cAAcA;4BACdI,oBAAoBI;4BACpB+B,UAAU,CAACE;gCACTtC,SAAS;oCAACe,MAAM;oCAAqBR,UAAU+B;gCAAK;4BACtD;2BALKvC,WAAWS,SAAS;;;;0BAWjC,KAACzC;gBACCwE,MACExC,WAAWO,IAAI,KAAK,wBAAwBP,WAAWO,IAAI,KAAK;gBAElEkC,cAAc,CAACD;oBACb,IAAI,CAACA,QAAQxC,WAAWO,IAAI,KAAK,sBAAsBN,SAAS;wBAACe,MAAM;oBAAM;gBAC/E;0BAEA,cAAA,MAAC/C;oBAAayE,oBAAkBC;;sCAC9B,KAACxE;4BAAWyD,WAAU;sCACnB5B,WAAWO,IAAI,KAAK,wBACrBP,WAAWO,IAAI,KAAK,2BAChB,CAAC,UAAU,EAAEP,WAAWQ,QAAQ,CAACU,KAAK,EAAE,GACxC;;sCAEN,KAAChD;sCACC,cAAA,KAACK;gCACC0D,MAAK;gCACLW,eAAY;gCACZhB,WAAU;0CAET5B,WAAWO,IAAI,KAAK,wBACrBP,WAAWO,IAAI,KAAK,2BAChB,CAAC,UAAU,EAAEP,WAAWQ,QAAQ,CAACU,KAAK,EAAE,GACxC;;;wBAGPlB,WAAWO,IAAI,KAAK,wBACrBP,WAAWO,IAAI,KAAK,yCAClB,MAACoB;4BAAIC,WAAU;;gCACZ5B,WAAWO,IAAI,KAAK,yCACnB,KAACoB;oCAAIkB,MAAK;oCAASjB,WAAU;8CAC3B,cAAA,KAACrD;wCAAK0D,MAAK;wCAAKL,WAAU;kDAAgC;;qCAI1D;gCACH5B,WAAWO,IAAI,KAAK,4BAA4BP,WAAWoB,KAAK,iBAC/D,KAACO;oCAAIC,WAAU;8CACb,cAAA,KAAC/D;wCAAQgF,MAAK;wCAAQ7B,MAAK;kDACzB,cAAA,MAACW;4CAAIC,WAAU;;8DACb,KAACrD;oDAAK0D,MAAK;oDAAKa,IAAI;8DAAC;;8DAGrB,KAACvE;oDAAK0D,MAAK;8DAAMjC,WAAWoB,KAAK;;;;;qCAIrC;8CACJ,KAACO;oCAAIC,WAAU;8CACb,cAAA,KAAC7C;wCACCY,aAAaA;wCACb4C,OAAOvC,WAAWQ,QAAQ;wCAC1BuC,kBAAkB;wCAClBC,SAAS;4CACP,KAAKjC;wCACP;;;;6BAIJ;;;;;;AAKd;AAEA,SAASqB,cAAc,EAACC,QAAQ,EAA2C;IACzE,qBACE,KAACY;QAAGrB,WAAW/C;QAAqBqE,cAAW;kBAC5ChE,gBAAgBiE,GAAG,CAAC,CAAC1B,wBACpB,KAAC2B;gBAA6B3B,SAASA;gBAAS4B,UAAU,IAAMhB,SAASZ,QAAQf,EAAE;eAAjEe,QAAQf,EAAE;;AAIpC;AAEA,SAAS0C,YAAY,EAAC3B,OAAO,EAAE4B,QAAQ,EAAqD;IAC1F,qBACE,KAACC;kBACC,cAAA,KAACC;YACCvC,MAAK;YACLY,WAAWpD,GACT,6KACAiB;YAEFyD,cAAY,CAAC,OAAO,EAAEzB,QAAQP,KAAK,EAAE;YACrCc,SAASqB;sBAET,cAAA,MAAC1B;gBAAIC,WAAU;;kCACb,MAACD;wBAAIC,WAAU;;0CACb,KAACrD;gCAAK0D,MAAK;gCAAKa,IAAI;gCAAClB,WAAU;0CAC5BH,QAAQP,KAAK;;0CAEhB,KAAC3C;gCAAK0D,MAAK;gCAAKL,WAAU;0CACvBH,QAAQ+B,WAAW;;;;kCAGxB,MAAC7B;wBAAIC,WAAU;;0CACb,KAACrD;gCAAK0D,MAAK;0CAAK;;0CAChB,KAAClE;gCAAK0F,MAAK;gCAAe7B,WAAU;;;;;;;;AAMhD;AAEA,SAASU,oBAAoB,EAC3BxC,YAAY,EACZI,kBAAkB,EAClBmC,QAAQ,EAKT;IACC,IAAIvC,aAAa4D,SAAS,EAAE;QAC1B,qBACE,KAAC/B;YAAIkB,MAAK;YAASc,aAAU;YAAOT,cAAW;sBAC7C,cAAA,KAACU;;IAGP;IAEA,IAAI9D,aAAa+D,OAAO,IAAI/D,aAAaK,IAAI,KAAKwC,WAAW;QAC3D,qBAAO,KAAChF;YAAemG,OAAOhE;YAAciE,SAAQ;;IACtD;IAEA,IAAIjE,aAAaK,IAAI,KAAKwC,aAAazC,mBAAmB8D,MAAM,KAAK,GAAG;QACtE,qBACE,KAAClG;YACCmG,MAAK;YACLC,OAAM;YACNV,aAAY;;IAGlB;IAEA,qBAAO,KAAC5E;QAAuBuF,SAASjE;QAAoBmC,UAAUA;;AACxE;AAEA,SAASuB;IACP,qBACE,KAACjC;QAAIC,WAAW/C;kBACb;YAAC;YAAG;YAAG;YAAG;SAAE,CAACsE,GAAG,CAAC,CAACiB,qBACjB,KAAChG;gBAAoBwD,WAAU;eAAhBwC;;AAIvB"}
|
|
1
|
+
{"version":3,"sources":["../../src/pages/model-provider-onboarding-page.tsx"],"sourcesContent":["import {QueryLoadError} from '@shipfox/client-ui';\nimport {Button} from '@shipfox/react-ui/button';\nimport {Callout} from '@shipfox/react-ui/callout';\nimport {EmptyState} from '@shipfox/react-ui/empty-state';\nimport {Icon} from '@shipfox/react-ui/icon';\nimport {Modal, ModalContent, ModalHeader, ModalTitle} from '@shipfox/react-ui/modal';\nimport {Skeleton} from '@shipfox/react-ui/skeleton';\nimport {toast} from '@shipfox/react-ui/toast';\nimport {Header, Text} from '@shipfox/react-ui/typography';\nimport {cn} from '@shipfox/react-ui/utils';\nimport {useEffect, useMemo, useReducer} from 'react';\nimport {AvailableProvidersGrid, PROVIDER_GRID_CLASS} from '#components/available-providers-grid.js';\nimport {modelProviderConfigErrorToFormError} from '#components/form-errors.js';\nimport {ModelProviderTestAndSaveForm} from '#components/test-and-save-form.js';\nimport {DEFAULT_HARNESS, harnessSupportsProvider, listHarnesses} from '#core/harness-policy.js';\nimport type {HarnessDescriptor, HarnessId, SupportedProvider} from '#core/models.js';\nimport {initialOnboardingState, onboardingReducer} from '#core/onboarding-reducer.js';\nimport {isSupportedProvider} from '#core/provider-policy.js';\nimport {\n useModelProviderCatalogQuery,\n useSetDefaultHarnessMutation,\n} from '#hooks/api/model-providers.js';\nimport {dismissModelProviderOnboarding} from '#state/model-provider-onboarding.js';\n\nconst SURFACE_CLASS =\n 'overflow-hidden rounded-8 border border-border-neutral-base bg-background-neutral-base';\n\nexport function ModelProviderOnboardingPage({\n workspaceId,\n onSkip,\n onConfigured,\n}: {\n workspaceId: string;\n onSkip: () => void;\n onConfigured: () => void;\n}) {\n const catalogQuery = useModelProviderCatalogQuery();\n const setDefaultHarness = useSetDefaultHarnessMutation();\n const [onboarding, dispatch] = useReducer(onboardingReducer, initialOnboardingState);\n const supportedProviders = catalogQuery.data?.providers.filter(isSupportedProvider) ?? [];\n const filteredProviders = useMemo(() => {\n if (onboarding.step === 'choose-harness') return [];\n return supportedProviders.filter((provider) =>\n harnessSupportsProvider(onboarding.harnessId, provider.id),\n );\n }, [onboarding, supportedProviders]);\n\n useEffect(() => {\n document\n .getElementById(\n onboarding.step === 'choose-harness'\n ? 'model-provider-harness-step'\n : 'model-provider-provider-step',\n )\n ?.focus();\n }, [onboarding.step]);\n\n function handleSkip() {\n try {\n dismissModelProviderOnboarding(workspaceId);\n } catch {\n // Skip is best-effort persistence; access to the product must not depend on storage.\n }\n onSkip();\n }\n\n async function handleProviderSaved() {\n if (onboarding.step !== 'configure-provider' && onboarding.step !== 'saving-default-harness')\n return;\n\n const provider = onboarding.provider;\n if (onboarding.step === 'configure-provider') dispatch({type: 'provider-saved'});\n if (onboarding.harnessId === DEFAULT_HARNESS) {\n toast.success(`${provider.label} saved`);\n dispatch({type: 'default-harness-saved'});\n onConfigured();\n return;\n }\n\n try {\n await setDefaultHarness.mutateAsync({\n workspaceId,\n harnessId: onboarding.harnessId,\n });\n toast.success(`${provider.label} saved`);\n dispatch({type: 'default-harness-saved'});\n onConfigured();\n } catch (error) {\n const mapped = modelProviderConfigErrorToFormError(error);\n dispatch({\n type: 'default-harness-failed',\n message: mapped.message || 'Could not save default harness. Try again.',\n });\n }\n }\n\n const selectedHarnessDescriptor =\n onboarding.step === 'choose-harness'\n ? null\n : listHarnesses().find((harness) => harness.id === onboarding.harnessId);\n const headingId =\n onboarding.step === 'choose-harness'\n ? 'model-provider-harness-step'\n : 'model-provider-provider-step';\n\n return (\n <div className=\"mx-auto flex w-full flex-col gap-section\">\n <header className=\"flex flex-col gap-cluster\">\n <div className=\"flex items-start justify-between gap-group max-[520px]:flex-col max-[520px]:gap-inline\">\n <Header id={headingId} variant=\"h1\" tabIndex={-1} className=\"outline-none\">\n {selectedHarnessDescriptor\n ? `Configure ${selectedHarnessDescriptor.label}`\n : 'Choose agent harness'}\n </Header>\n <Button type=\"button\" variant=\"secondary\" onClick={handleSkip} className=\"shrink-0\">\n Skip for now\n </Button>\n </div>\n <Text size=\"md\" className=\"text-foreground-neutral-muted\">\n {selectedHarnessDescriptor\n ? `${selectedHarnessDescriptor.label} needs a compatible model provider. Add your own API key, or go back to choose a different harness.`\n : 'A harness runs agent steps. Choose the engine you want first, then connect a compatible model provider.'}\n </Text>\n </header>\n\n <section aria-labelledby={headingId} className=\"flex flex-col gap-group\">\n {onboarding.step === 'choose-harness' ? (\n <HarnessPicker\n onSelect={(harnessId) => dispatch({type: 'harness-selected', harnessId})}\n />\n ) : (\n <>\n <div>\n <Button type=\"button\" variant=\"transparent\" onClick={() => dispatch({type: 'back'})}>\n Back\n </Button>\n </div>\n <ModelProviderPicker\n key={onboarding.harnessId}\n catalogQuery={catalogQuery}\n supportedProviders={filteredProviders}\n onSelect={(entry) => {\n dispatch({type: 'provider-selected', provider: entry});\n }}\n />\n </>\n )}\n </section>\n\n <Modal\n open={\n onboarding.step === 'configure-provider' || onboarding.step === 'saving-default-harness'\n }\n onOpenChange={(open) => {\n if (!open && onboarding.step === 'configure-provider') dispatch({type: 'back'});\n }}\n >\n <ModalContent aria-describedby={undefined}>\n <ModalTitle className=\"sr-only\">\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness'\n ? `Configure ${onboarding.provider.label}`\n : ''}\n </ModalTitle>\n <ModalHeader>\n <Text\n size=\"lg\"\n aria-hidden=\"true\"\n className=\"overflow-ellipsis overflow-hidden whitespace-nowrap\"\n >\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness'\n ? `Configure ${onboarding.provider.label}`\n : ''}\n </Text>\n </ModalHeader>\n {onboarding.step === 'configure-provider' ||\n onboarding.step === 'saving-default-harness' ? (\n <div className=\"flex min-h-0 flex-1 flex-col gap-inline\">\n {onboarding.step === 'saving-default-harness' ? (\n <div role=\"status\" className=\"px-row\">\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n Saving harness default...\n </Text>\n </div>\n ) : null}\n {onboarding.step === 'saving-default-harness' && onboarding.error ? (\n <div className=\"px-row\">\n <Callout role=\"alert\" type=\"error\">\n <div className=\"flex flex-col gap-inline\">\n <Text size=\"sm\" bold>\n Could not save default harness\n </Text>\n <Text size=\"sm\">{onboarding.error}</Text>\n </div>\n </Callout>\n </div>\n ) : null}\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <ModelProviderTestAndSaveForm\n workspaceId={workspaceId}\n entry={onboarding.provider}\n setAsDefaultOnSave\n onSaved={() => {\n void handleProviderSaved();\n }}\n />\n </div>\n </div>\n ) : null}\n </ModalContent>\n </Modal>\n </div>\n );\n}\n\nfunction HarnessPicker({onSelect}: {onSelect: (harness: HarnessId) => void}) {\n return (\n <ul className={PROVIDER_GRID_CLASS} aria-label=\"Agent harnesses\">\n {listHarnesses().map((harness) => (\n <HarnessCard key={harness.id} harness={harness} onChoose={() => onSelect(harness.id)} />\n ))}\n </ul>\n );\n}\n\nfunction HarnessCard({harness, onChoose}: {harness: HarnessDescriptor; onChoose: () => void}) {\n return (\n <li>\n <button\n type=\"button\"\n className={cn(\n 'group block w-full cursor-pointer p-panel-compact text-left outline-none transition-colors hover:bg-background-components-hover focus-visible:shadow-button-neutral-focus',\n SURFACE_CLASS,\n )}\n aria-label={`Choose ${harness.label}`}\n onClick={onChoose}\n >\n <div className=\"flex min-w-0 items-center justify-between gap-cluster\">\n <div className=\"flex min-w-0 flex-col gap-tight\">\n <Text size=\"md\" bold className=\"min-w-0 truncate\">\n {harness.label}\n </Text>\n <Text size=\"sm\" className=\"text-foreground-neutral-muted\">\n {harness.description}\n </Text>\n </div>\n <div className=\"flex shrink-0 items-center gap-tight text-foreground-neutral-muted transition-colors group-hover:text-foreground-highlight-interactive\">\n <Text size=\"sm\">Choose</Text>\n <Icon name=\"chevronRight\" className=\"size-16\" />\n </div>\n </div>\n </button>\n </li>\n );\n}\n\nfunction ModelProviderPicker({\n catalogQuery,\n supportedProviders,\n onSelect,\n}: {\n catalogQuery: ReturnType<typeof useModelProviderCatalogQuery>;\n supportedProviders: SupportedProvider[];\n onSelect: (entry: SupportedProvider) => void;\n}) {\n if (catalogQuery.isPending) {\n return (\n <div role=\"status\" aria-busy=\"true\" aria-label=\"Loading model providers\">\n <ModelProviderGridSkeleton />\n </div>\n );\n }\n\n if (catalogQuery.isError && catalogQuery.data === undefined) {\n return <QueryLoadError query={catalogQuery} subject=\"model provider catalog\" />;\n }\n\n if (catalogQuery.data !== undefined && supportedProviders.length === 0) {\n return (\n <EmptyState\n icon=\"componentLine\"\n title=\"No providers available to configure\"\n description=\"Skip for now and add one later from workspace settings.\"\n />\n );\n }\n\n return <AvailableProvidersGrid entries={supportedProviders} onSelect={onSelect} />;\n}\n\nfunction ModelProviderGridSkeleton() {\n return (\n <div className={PROVIDER_GRID_CLASS}>\n {[0, 1, 2, 3].map((card) => (\n <Skeleton key={card} className=\"h-136 w-full\" />\n ))}\n </div>\n );\n}\n"],"names":["QueryLoadError","Button","Callout","EmptyState","Icon","Modal","ModalContent","ModalHeader","ModalTitle","Skeleton","toast","Header","Text","cn","useEffect","useMemo","useReducer","AvailableProvidersGrid","PROVIDER_GRID_CLASS","modelProviderConfigErrorToFormError","ModelProviderTestAndSaveForm","DEFAULT_HARNESS","harnessSupportsProvider","listHarnesses","initialOnboardingState","onboardingReducer","isSupportedProvider","useModelProviderCatalogQuery","useSetDefaultHarnessMutation","dismissModelProviderOnboarding","SURFACE_CLASS","ModelProviderOnboardingPage","workspaceId","onSkip","onConfigured","catalogQuery","setDefaultHarness","onboarding","dispatch","supportedProviders","data","providers","filter","filteredProviders","step","provider","harnessId","id","document","getElementById","focus","handleSkip","handleProviderSaved","type","success","label","mutateAsync","error","mapped","message","selectedHarnessDescriptor","find","harness","headingId","div","className","header","variant","tabIndex","onClick","size","section","aria-labelledby","HarnessPicker","onSelect","ModelProviderPicker","entry","open","onOpenChange","aria-describedby","undefined","aria-hidden","role","bold","setAsDefaultOnSave","onSaved","ul","aria-label","map","HarnessCard","onChoose","li","button","description","name","isPending","aria-busy","ModelProviderGridSkeleton","isError","query","subject","length","icon","title","entries","card"],"mappings":"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"}
|
|
@@ -150,7 +150,7 @@ function ModelProviderOnboardingStory({ scenario }) {
|
|
|
150
150
|
client: queryClient,
|
|
151
151
|
children: [
|
|
152
152
|
/*#__PURE__*/ _jsx("div", {
|
|
153
|
-
className: "bg-background-
|
|
153
|
+
className: "bg-background-subtle-base px-24 py-32",
|
|
154
154
|
children: /*#__PURE__*/ _jsx(ModelProviderOnboardingPage, {
|
|
155
155
|
workspaceId: WORKSPACE_ID,
|
|
156
156
|
onSkip: ()=>undefined,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/pages/model-provider-onboarding-page.stories.tsx"],"sourcesContent":["import type {ModelProviderCatalogEntryDto, ModelProviderConfigDto} 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 {ModelProviderOnboardingPage} from './model-provider-onboarding-page.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario = 'available' | 'loading' | 'catalog-error' | 'no-providers' | 'long-names';\n\ninterface ModelProviderOnboardingStoryProps {\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 ModelProviderOnboardingStory({scenario}: ModelProviderOnboardingStoryProps) {\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=\"bg-background-neutral-background px-24 py-32\">\n <ModelProviderOnboardingPage\n workspaceId={WORKSPACE_ID}\n onSkip={() => undefined}\n onConfigured={() => undefined}\n />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderOnboarding',\n component: ModelProviderOnboardingStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'available'},\n} satisfies Meta<typeof ModelProviderOnboardingStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const CatalogError: Story = {\n args: {scenario: 'catalog-error'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const NoProvidersAvailable: Story = {\n args: {scenario: 'no-providers'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const FilteredProviders: Story = {\n args: {scenario: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\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 NoMatchingProviders: Story = {\n args: {scenario: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\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: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure Anthropic'}));\n await screen.findByLabelText('API key');\n },\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input) => {\n const url = requestUrl(input);\n const request = input instanceof Request ? input : undefined;\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 (request?.method === 'PUT' && url.pathname.includes('/agent/model-providers/')) {\n return Promise.resolve(\n jsonResponse(\n providerConfig({\n provider_id: url.pathname.endsWith('/openai') ? 'openai' : 'anthropic',\n }),\n ),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction catalogForScenario(scenario: Scenario): ModelProviderCatalogEntryDto[] {\n if (scenario === 'no-providers') return [];\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 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","ModelProviderOnboardingPage","WORKSPACE_ID","CATALOG","providerEntry","id","label","default_model","models","support_status","credential_fields","unsupported_reason","ModelProviderOnboardingStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","onSkip","undefined","onConfigured","meta","title","component","parameters","layout","args","Playground","Loading","play","canvasElement","canvas","click","getByRole","name","CatalogError","NoProvidersAvailable","LongNames","FilteredProviders","type","findByRole","NoMatchingProviders","ConfigureModalOpen","findByLabelText","input","url","requestUrl","request","Request","Promise","pathname","endsWith","resolve","errorResponse","jsonResponse","providers","catalogForScenario","method","includes","providerConfig","provider_id","status","overrides","key","secret","kind","created_at","updated_at","URL","body","init","Response","JSON","stringify","headers","code","statusText"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["../../src/pages/model-provider-onboarding-page.stories.tsx"],"sourcesContent":["import type {ModelProviderCatalogEntryDto, ModelProviderConfigDto} 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 {ModelProviderOnboardingPage} from './model-provider-onboarding-page.js';\n\nconst WORKSPACE_ID = '11111111-1111-4111-8111-111111111111';\n\ntype Scenario = 'available' | 'loading' | 'catalog-error' | 'no-providers' | 'long-names';\n\ninterface ModelProviderOnboardingStoryProps {\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 ModelProviderOnboardingStory({scenario}: ModelProviderOnboardingStoryProps) {\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=\"bg-background-subtle-base px-24 py-32\">\n <ModelProviderOnboardingPage\n workspaceId={WORKSPACE_ID}\n onSkip={() => undefined}\n onConfigured={() => undefined}\n />\n </div>\n <Toaster />\n </QueryClientProvider>\n );\n}\n\nconst meta = {\n title: 'Agent/ProviderOnboarding',\n component: ModelProviderOnboardingStory,\n parameters: {layout: 'fullscreen'},\n args: {scenario: 'available'},\n} satisfies Meta<typeof ModelProviderOnboardingStory>;\n\nexport default meta;\ntype Story = StoryObj<typeof meta>;\n\nexport const Playground: Story = {};\n\nexport const Loading: Story = {\n args: {scenario: 'loading'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const CatalogError: Story = {\n args: {scenario: 'catalog-error'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const NoProvidersAvailable: Story = {\n args: {scenario: 'no-providers'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const LongNames: Story = {\n args: {scenario: 'long-names'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n },\n};\n\nexport const FilteredProviders: Story = {\n args: {scenario: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\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 NoMatchingProviders: Story = {\n args: {scenario: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\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: 'available'},\n play: async ({canvasElement}) => {\n const canvas = within(canvasElement);\n await userEvent.click(canvas.getByRole('button', {name: 'Choose pi'}));\n await userEvent.click(await canvas.findByRole('button', {name: 'Configure Anthropic'}));\n await screen.findByLabelText('API key');\n },\n};\n\nfunction fetchForScenario(scenario: Scenario): typeof fetch {\n return (input) => {\n const url = requestUrl(input);\n const request = input instanceof Request ? input : undefined;\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 (request?.method === 'PUT' && url.pathname.includes('/agent/model-providers/')) {\n return Promise.resolve(\n jsonResponse(\n providerConfig({\n provider_id: url.pathname.endsWith('/openai') ? 'openai' : 'anthropic',\n }),\n ),\n );\n }\n return Promise.resolve(jsonResponse({}, {status: 404}));\n };\n}\n\nfunction catalogForScenario(scenario: Scenario): ModelProviderCatalogEntryDto[] {\n if (scenario === 'no-providers') return [];\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 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","ModelProviderOnboardingPage","WORKSPACE_ID","CATALOG","providerEntry","id","label","default_model","models","support_status","credential_fields","unsupported_reason","ModelProviderOnboardingStory","scenario","baseUrl","fetchImpl","fetchForScenario","queryClient","defaultOptions","queries","retry","client","div","className","workspaceId","onSkip","undefined","onConfigured","meta","title","component","parameters","layout","args","Playground","Loading","play","canvasElement","canvas","click","getByRole","name","CatalogError","NoProvidersAvailable","LongNames","FilteredProviders","type","findByRole","NoMatchingProviders","ConfigureModalOpen","findByLabelText","input","url","requestUrl","request","Request","Promise","pathname","endsWith","resolve","errorResponse","jsonResponse","providers","catalogForScenario","method","includes","providerConfig","provider_id","status","overrides","key","secret","kind","created_at","updated_at","URL","body","init","Response","JSON","stringify","headers","code","statusText"],"mappings":"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"}
|
|
@@ -2,6 +2,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { defineRoute, useActiveWorkspace } from '@shipfox/client-shell/runtime';
|
|
3
3
|
import { WorkspaceHarnessesSection, WorkspaceModelProvidersSection } from '#index.js';
|
|
4
4
|
export default defineRoute({
|
|
5
|
+
staticData: {
|
|
6
|
+
frame: 'content'
|
|
7
|
+
},
|
|
5
8
|
component: ()=>{
|
|
6
9
|
const workspace = useActiveWorkspace();
|
|
7
10
|
return /*#__PURE__*/ _jsxs("div", {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/agents-settings.tsx"],"sourcesContent":["import {defineRoute, useActiveWorkspace} from '@shipfox/client-shell/runtime';\nimport {WorkspaceHarnessesSection, WorkspaceModelProvidersSection} from '#index.js';\n\nexport default defineRoute({\n component: () => {\n const workspace = useActiveWorkspace();\n return (\n <div className=\"flex flex-col gap-region\">\n <WorkspaceHarnessesSection workspaceId={workspace.id} />\n <WorkspaceModelProvidersSection workspaceId={workspace.id} />\n </div>\n );\n },\n});\n"],"names":["defineRoute","useActiveWorkspace","WorkspaceHarnessesSection","WorkspaceModelProvidersSection","component","workspace","div","className","workspaceId","id"],"mappings":";AAAA,SAAQA,WAAW,EAAEC,kBAAkB,QAAO,gCAAgC;AAC9E,SAAQC,yBAAyB,EAAEC,8BAA8B,QAAO,YAAY;AAEpF,eAAeH,YAAY;IACzBI,WAAW;QACT,MAAMC,
|
|
1
|
+
{"version":3,"sources":["../../src/routes/agents-settings.tsx"],"sourcesContent":["import {defineRoute, useActiveWorkspace} from '@shipfox/client-shell/runtime';\nimport {WorkspaceHarnessesSection, WorkspaceModelProvidersSection} from '#index.js';\n\nexport default defineRoute({\n staticData: {frame: 'content'},\n component: () => {\n const workspace = useActiveWorkspace();\n return (\n <div className=\"flex flex-col gap-region\">\n <WorkspaceHarnessesSection workspaceId={workspace.id} />\n <WorkspaceModelProvidersSection workspaceId={workspace.id} />\n </div>\n );\n },\n});\n"],"names":["defineRoute","useActiveWorkspace","WorkspaceHarnessesSection","WorkspaceModelProvidersSection","staticData","frame","component","workspace","div","className","workspaceId","id"],"mappings":";AAAA,SAAQA,WAAW,EAAEC,kBAAkB,QAAO,gCAAgC;AAC9E,SAAQC,yBAAyB,EAAEC,8BAA8B,QAAO,YAAY;AAEpF,eAAeH,YAAY;IACzBI,YAAY;QAACC,OAAO;IAAS;IAC7BC,WAAW;QACT,MAAMC,YAAYN;QAClB,qBACE,MAACO;YAAIC,WAAU;;8BACb,KAACP;oBAA0BQ,aAAaH,UAAUI,EAAE;;8BACpD,KAACR;oBAA+BO,aAAaH,UAAUI,EAAE;;;;IAG/D;AACF,GAAG"}
|
|
@@ -4,6 +4,9 @@ import { useNavigate } from '@tanstack/react-router';
|
|
|
4
4
|
import { ModelProviderOnboardingPage } from '#pages/model-provider-onboarding-page.js';
|
|
5
5
|
import { modelProviderRouteParams } from './inputs.js';
|
|
6
6
|
export default defineRoute({
|
|
7
|
+
staticData: {
|
|
8
|
+
frame: 'focused'
|
|
9
|
+
},
|
|
7
10
|
component: ()=>{
|
|
8
11
|
const { workspaceSlug } = useRouteParams(modelProviderRouteParams);
|
|
9
12
|
const workspace = useActiveWorkspace();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/routes/model-provider.tsx"],"sourcesContent":["import {defineRoute, useActiveWorkspace, useRouteParams} from '@shipfox/client-shell/runtime';\nimport {useNavigate} from '@tanstack/react-router';\nimport {ModelProviderOnboardingPage} from '#pages/model-provider-onboarding-page.js';\nimport {modelProviderRouteParams} from './inputs.js';\n\nexport default defineRoute({\n component: () => {\n const {workspaceSlug} = useRouteParams(modelProviderRouteParams);\n const workspace = useActiveWorkspace();\n const navigate = useNavigate();\n const goToProjectCreation = () => {\n void navigate({to: '/w/$workspaceSlug/projects/new', params: {workspaceSlug}, replace: true});\n };\n return (\n <ModelProviderOnboardingPage\n workspaceId={workspace.id}\n onSkip={goToProjectCreation}\n onConfigured={goToProjectCreation}\n />\n );\n },\n});\n"],"names":["defineRoute","useActiveWorkspace","useRouteParams","useNavigate","ModelProviderOnboardingPage","modelProviderRouteParams","component","workspaceSlug","workspace","navigate","goToProjectCreation","to","params","replace","workspaceId","id","onSkip","onConfigured"],"mappings":";AAAA,SAAQA,WAAW,EAAEC,kBAAkB,EAAEC,cAAc,QAAO,gCAAgC;AAC9F,SAAQC,WAAW,QAAO,yBAAyB;AACnD,SAAQC,2BAA2B,QAAO,2CAA2C;AACrF,SAAQC,wBAAwB,QAAO,cAAc;AAErD,eAAeL,YAAY;IACzBM,WAAW;QACT,MAAM,EAACC,aAAa,EAAC,
|
|
1
|
+
{"version":3,"sources":["../../src/routes/model-provider.tsx"],"sourcesContent":["import {defineRoute, useActiveWorkspace, useRouteParams} from '@shipfox/client-shell/runtime';\nimport {useNavigate} from '@tanstack/react-router';\nimport {ModelProviderOnboardingPage} from '#pages/model-provider-onboarding-page.js';\nimport {modelProviderRouteParams} from './inputs.js';\n\nexport default defineRoute({\n staticData: {frame: 'focused'},\n component: () => {\n const {workspaceSlug} = useRouteParams(modelProviderRouteParams);\n const workspace = useActiveWorkspace();\n const navigate = useNavigate();\n const goToProjectCreation = () => {\n void navigate({to: '/w/$workspaceSlug/projects/new', params: {workspaceSlug}, replace: true});\n };\n return (\n <ModelProviderOnboardingPage\n workspaceId={workspace.id}\n onSkip={goToProjectCreation}\n onConfigured={goToProjectCreation}\n />\n );\n },\n});\n"],"names":["defineRoute","useActiveWorkspace","useRouteParams","useNavigate","ModelProviderOnboardingPage","modelProviderRouteParams","staticData","frame","component","workspaceSlug","workspace","navigate","goToProjectCreation","to","params","replace","workspaceId","id","onSkip","onConfigured"],"mappings":";AAAA,SAAQA,WAAW,EAAEC,kBAAkB,EAAEC,cAAc,QAAO,gCAAgC;AAC9F,SAAQC,WAAW,QAAO,yBAAyB;AACnD,SAAQC,2BAA2B,QAAO,2CAA2C;AACrF,SAAQC,wBAAwB,QAAO,cAAc;AAErD,eAAeL,YAAY;IACzBM,YAAY;QAACC,OAAO;IAAS;IAC7BC,WAAW;QACT,MAAM,EAACC,aAAa,EAAC,GAAGP,eAAeG;QACvC,MAAMK,YAAYT;QAClB,MAAMU,WAAWR;QACjB,MAAMS,sBAAsB;YAC1B,KAAKD,SAAS;gBAACE,IAAI;gBAAkCC,QAAQ;oBAACL;gBAAa;gBAAGM,SAAS;YAAI;QAC7F;QACA,qBACE,KAACX;YACCY,aAAaN,UAAUO,EAAE;YACzBC,QAAQN;YACRO,cAAcP;;IAGpB;AACF,GAAG"}
|