diff --git a/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx b/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx
index fa4db11099b..2494f20cf56 100644
--- a/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx
+++ b/libs/domains/services/feature/src/lib/service-creation-flow/agentic-workflow/agentic-workflow-configuration/agentic-workflow-configuration.tsx
@@ -1,7 +1,17 @@
import { type IconName } from '@fortawesome/fontawesome-common-types'
import { useNavigate } from '@tanstack/react-router'
import { type ReactNode, useEffect, useRef } from 'react'
-import { Button, CodeEditor, FunnelFlowBody, Icon, InputText, InputTextArea, InputToggle } from '@qovery/shared/ui'
+import {
+ Button,
+ CodeEditor,
+ FunnelFlowBody,
+ Heading,
+ Icon,
+ InputText,
+ InputTextArea,
+ InputToggle,
+ Section,
+} from '@qovery/shared/ui'
import {
type AgenticWorkflowConfigurationSection,
type AgenticWorkflowGitRepository,
@@ -89,11 +99,7 @@ function AgenticWorkflowSection({
<>
-
- {title}
-
+ {title}
{showStatus &&
@@ -107,7 +113,7 @@ function AgenticWorkflowSection({
)
return (
-
+
{active ? (
{headerContent}
@@ -124,7 +130,7 @@ function AgenticWorkflowSection({
)}
{active &&
{children}
}
-
+
)
}
@@ -281,327 +287,329 @@ export function AgenticWorkflowConfiguration() {
return (
-
- Create agentic workflow
-
- Configure the inputs, tools, model, governance, and outputs used by your workflow.
-
-
+
+
+ Create agentic workflow
+
+ Configure the inputs, tools, model, governance, and outputs used by your workflow.
+
+
-
-
- form.setValue('name', event.currentTarget.value, { shouldDirty: true })}
- />
- form.setValue('description', event.currentTarget.value, { shouldDirty: true })}
- />
-
+
+
form.setValue('cpu', event.currentTarget.value, { shouldDirty: true })}
+ name="name"
+ label="Name"
+ value={values.name}
+ autoFocus
+ error={showNameError ? 'Please enter a workflow name.' : undefined}
+ onChange={(event) => form.setValue('name', event.currentTarget.value, { shouldDirty: true })}
/>
- form.setValue('memory', event.currentTarget.value, { shouldDirty: true })}
+ form.setValue('description', event.currentTarget.value, { shouldDirty: true })}
/>
+
+ form.setValue('cpu', event.currentTarget.value, { shouldDirty: true })}
+ />
+ form.setValue('memory', event.currentTarget.value, { shouldDirty: true })}
+ />
+ form.setValue('storage', event.currentTarget.value, { shouldDirty: true })}
+ />
+
+ form.setValue('workflowEnabled', value, { shouldDirty: true })}
+ />
+
+
+
+
+
form.setValue('storage', event.currentTarget.value, { shouldDirty: true })}
+ ref={modelApiKeyInputRef}
+ name="model-api-key"
+ label="API key"
+ type="password"
+ value={values.modelApiKey}
+ hint="API key used to call the selected cloud model."
+ error={showModelApiKeyError ? 'Please enter an API key.' : undefined}
+ onChange={(event) => form.setValue('modelApiKey', event.currentTarget.value, { shouldDirty: true })}
/>
-
-
form.setValue('workflowEnabled', value, { shouldDirty: true })}
- />
-
-
+
+ Need help configuring Claude Code settings? Read the{' '}
+
+ Claude Code settings documentation
+
+ .
+ >
+ }
+ onChange={(value) => form.setValue('modelSettingsJson', value, { shouldDirty: true })}
+ />
+
+
-
-
- form.setValue('modelApiKey', event.currentTarget.value, { shouldDirty: true })}
- />
-
- Need help configuring Claude Code settings? Read the{' '}
-
- Claude Code settings documentation
-
- .
- >
- }
- onChange={(value) => form.setValue('modelSettingsJson', value, { shouldDirty: true })}
- />
-
-
+
+
+ See Claude Code docs for{' '}
+
+ remote HTTP
+ {' '}
+ and{' '}
+
+ local stdio
+ {' '}
+ servers.
+
+ }
+ onChange={(value) => form.setValue('mcpJson', value, { shouldDirty: true })}
+ />
+
+
-
-
- See Claude Code docs for{' '}
-
- remote HTTP
- {' '}
- and{' '}
-
- local stdio
- {' '}
- servers.
-
+
+
+ Add repository
+
}
- onChange={(value) => form.setValue('mcpJson', value, { shouldDirty: true })}
- />
-
-
+ >
+ {values.gitRepositories.map((repository, index) => (
+ {
+ const gitRepositories = [...values.gitRepositories]
+ gitRepositories[index] = nextRepository
+ form.setValue('gitRepositories', gitRepositories, { shouldDirty: true })
+ }}
+ onRemove={() =>
+ form.setValue(
+ 'gitRepositories',
+ values.gitRepositories.filter((_, repositoryIndex) => repositoryIndex !== index),
+ { shouldDirty: true }
+ )
+ }
+ />
+ ))}
+ {!gitRepositoriesValid && (
+
+ Select a Git account, repository, and branch for each repository.
+
+ )}
+
+
-
-
- Add repository
-
- }
- >
- {values.gitRepositories.map((repository, index) => (
- {
- const gitRepositories = [...values.gitRepositories]
- gitRepositories[index] = nextRepository
- form.setValue('gitRepositories', gitRepositories, { shouldDirty: true })
- }}
- onRemove={() =>
- form.setValue(
- 'gitRepositories',
- values.gitRepositories.filter((_, repositoryIndex) => repositoryIndex !== index),
- { shouldDirty: true }
- )
- }
+
+ form.setValue('whitelistHosts', event.currentTarget.value, { shouldDirty: true })}
/>
- ))}
- {!gitRepositoriesValid && (
-
- Select a Git account, repository, and branch for each repository.
-
- )}
-
-
+
+
-
- form.setValue('whitelistHosts', event.currentTarget.value, { shouldDirty: true })}
- />
-
-
+
+ form.setValue('dockerFragment', value, { shouldDirty: true })}
+ />
+
+
-
- form.setValue('dockerFragment', value, { shouldDirty: true })}
- />
-
-
+
+
+ Add webhook
+
+ }
+ >
+ {values.outputs.map((output, index) => (
+
+
+ Webhook {index + 1}
+
+
+
+ {
+ const outputs = [...values.outputs]
+ outputs[index] = { ...output, url: event.currentTarget.value }
+ form.setValue('outputs', outputs, { shouldDirty: true })
+ }}
+ />
+ {
+ const outputs = [...values.outputs]
+ outputs[index] = { ...output, headersJson: value }
+ form.setValue('outputs', outputs, { shouldDirty: true })
+ }}
+ />
+ {
+ const outputs = [...values.outputs]
+ outputs[index] = { ...output, prompt: event.currentTarget.value }
+ form.setValue('outputs', outputs, { shouldDirty: true })
+ }}
+ />
+
+
+ ))}
+ {!outputsValid && (
+
+ Enter a webhook URL for each configured output webhook.
+
+ )}
+
+
-
+ form.setValue('agentPrompt', event.currentTarget.value, { shouldDirty: true })}
+ />
+
+
+
+
+
+
+
)
}