@@ -54,9 +69,23 @@ export default function PluginPagesPage() {
const author = parts[0];
const pluginName = parts[1];
- // Use the asset path from the page manifest, not the page ID
- const assetPath = page?.path ?? parts.slice(2).join('/');
- const pageId = parts.slice(2).join('/');
+ if (!page) {
+ if (lookupCompleteForId === id) {
+ return (
+
+ {t('pluginPages.invalidPage')}
+
+ );
+ }
+ return (
+
+ Loading...
+
+ );
+ }
+
+ const assetPath = page.path;
+ const pageId = page.pageId;
return (
{
+ const url = httpClient.getPluginAssetURL(author, pluginName, pagePath);
+ const separator = url.includes('?') ? '&' : '?';
+ return `${url}${separator}_lb_page_v=${Date.now()}`;
+ }, [author, pluginName, pagePath]);
// Send context (theme + language) to iframe
// Use '*' as targetOrigin because sandboxed iframe has opaque (null) origin
diff --git a/web/src/app/infra/entities/form/dynamic.ts b/web/src/app/infra/entities/form/dynamic.ts
index 44fed3acf..5ea3d7e73 100644
--- a/web/src/app/infra/entities/form/dynamic.ts
+++ b/web/src/app/infra/entities/form/dynamic.ts
@@ -70,6 +70,11 @@ export enum DynamicFormItemType {
WEBHOOK_URL = 'webhook-url',
EMBED_CODE = 'embed-code',
QR_CODE_LOGIN = 'qr-code-login',
+ // Plugin manifest type aliases for compatibility
+ SELECT_LLM_MODEL = 'select-llm-model',
+ SELECT_KNOWLEDGE_BASES = 'select-knowledge-bases',
+ NUMBER = 'number',
+ JSON = 'json',
}
export interface IFileConfig {
diff --git a/web/src/app/wizard/page.tsx b/web/src/app/wizard/page.tsx
index a3afd07c4..955e008b4 100644
--- a/web/src/app/wizard/page.tsx
+++ b/web/src/app/wizard/page.tsx
@@ -86,7 +86,6 @@ export default function WizardPage() {
const [selectedAdapter, setSelectedAdapter] = useState(null);
const [selectedRunner, setSelectedRunner] = useState(null);
const [botName, setBotName] = useState('');
-
const [botDescription, _setBotDescription] = useState('');
const [adapterConfig, setAdapterConfig] = useState>(
{},
@@ -202,7 +201,7 @@ export default function WizardPage() {
const runnerOptions = useMemo(() => {
if (!runnerStage) return [];
- const runnerField = runnerStage.config.find((c) => c.name === 'runner');
+ const runnerField = runnerStage.config.find((c) => c.name === 'id');
return runnerField?.options ?? [];
}, [runnerStage]);
@@ -257,9 +256,11 @@ export default function WizardPage() {
const handleSelectRunner = useCallback(
(runner: string) => {
setSelectedRunner(runner);
+ const configStage = aiConfigTab?.stages.find((s) => s.name === runner);
+ setRunnerConfig(configStage ? getDefaultValues(configStage.config) : {});
saveProgress({ step: 2, selected_runner: runner });
},
- [saveProgress],
+ [aiConfigTab, saveProgress],
);
// ---- Navigation helpers ----
@@ -427,14 +428,36 @@ export default function WizardPage() {
// (includes trigger, safety, ai, output sections).
// Then merge only the AI section with the wizard's runner config.
const createdPipeline = await httpClient.getPipeline(pipelineResp.uuid);
- const fullConfig = createdPipeline.pipeline.config;
+ const fullConfig = createdPipeline.pipeline.config as unknown as Record<
+ string,
+ unknown
+ >;
+ const fullAiConfig =
+ fullConfig.ai && typeof fullConfig.ai === 'object'
+ ? (fullConfig.ai as Record)
+ : {};
+ const existingRunner =
+ fullAiConfig.runner && typeof fullAiConfig.runner === 'object'
+ ? (fullAiConfig.runner as Record)
+ : {};
+ const existingRunnerConfigs =
+ fullAiConfig.runner_config &&
+ typeof fullAiConfig.runner_config === 'object'
+ ? (fullAiConfig.runner_config as Record)
+ : {};
const mergedConfig = {
...fullConfig,
ai: {
- ...fullConfig.ai,
- runner: { runner: selectedRunner },
- [selectedRunner]: runnerConfig,
+ ...fullAiConfig,
+ runner: {
+ ...existingRunner,
+ id: selectedRunner,
+ },
+ runner_config: {
+ ...existingRunnerConfigs,
+ [selectedRunner]: runnerConfig,
+ },
},
};
@@ -1113,26 +1136,27 @@ function StepAIEngine({
})}
{/* Space promotion banner */}
- {selected === 'local-agent' && isLocalAccount && (
-
-
-
-
-
- {t('wizard.spaceBanner.message')}
-
-
+ {selected === 'plugin:langbot/local-agent/default' &&
+ isLocalAccount && (
+
+
+
+
+
+ {t('wizard.spaceBanner.message')}
+
+
+
-
- )}
+ )}