synthos 0.7.2 → 0.9.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/README.md +215 -65
- package/default-pages/application/page.html +42 -0
- package/default-pages/application/page.json +10 -0
- package/default-pages/elevenlabs_effects_studio/page.html +1363 -0
- package/default-pages/elevenlabs_effects_studio/page.json +11 -0
- package/default-pages/elevenlabs_voice_studio/page.html +801 -0
- package/default-pages/elevenlabs_voice_studio/page.json +11 -0
- package/default-pages/{json_tools.html → json_tools/page.html} +13 -11
- package/default-pages/json_tools/page.json +10 -0
- package/default-pages/my_notes/notes/a1b2c3d4-e5f6-7890-abcd-ef1234567890.json +5 -0
- package/default-pages/my_notes/page.html +132 -0
- package/default-pages/{my_notes.json → my_notes/page.json} +2 -2
- package/default-pages/neon_asteroids/files/Ambient_Space.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space2.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ambient_Space3.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Asteroid_Explosion.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Hyperspace_Jump.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Laser_Fire.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Menu_Navigate.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Power_Up_Collect.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Saucer_Alert.mp3 +0 -0
- package/default-pages/neon_asteroids/files/Ship_Thrust.mp3 +0 -0
- package/default-pages/neon_asteroids/files/effects.json +74 -0
- package/default-pages/neon_asteroids/page.html +1822 -0
- package/default-pages/{neon_asteroids.json → neon_asteroids/page.json} +3 -3
- package/default-pages/oregon_trail/page.html +323 -0
- package/default-pages/oregon_trail/page.json +12 -0
- package/default-pages/retro_game_starter/page.html +1308 -0
- package/default-pages/retro_game_starter/page.json +12 -0
- package/default-pages/{sidebar_builder.html → sidebar_page/page.html} +12 -10
- package/default-pages/sidebar_page/page.json +10 -0
- package/default-pages/{solar_explorer.html → solar_explorer/page.html} +24 -29
- package/default-pages/{solar_explorer.json → solar_explorer/page.json} +4 -4
- package/default-pages/{solar_tutorial.html → solar_tutorial/page.html} +12 -10
- package/default-pages/solar_tutorial/page.json +10 -0
- package/default-pages/{two-panel_builder.html → two-panel_page/page.html} +13 -11
- package/default-pages/two-panel_page/page.json +10 -0
- package/default-pages/us_map/page.html +193 -0
- package/default-pages/us_map/page.json +12 -0
- package/default-pages/us_map_1850/page.html +326 -0
- package/default-pages/us_map_1850/page.json +12 -0
- package/default-pages/western_cities_1850/page.html +527 -0
- package/default-pages/western_cities_1850/page.json +12 -0
- package/default-themes/aurora-dawn.json +19 -0
- package/default-themes/aurora-dawn.v3.css +198 -0
- package/default-themes/aurora-dusk.json +19 -0
- package/default-themes/aurora-dusk.v3.css +200 -0
- package/default-themes/cosmos-dawn.json +19 -0
- package/default-themes/cosmos-dawn.v3.css +198 -0
- package/default-themes/cosmos-dusk.json +19 -0
- package/default-themes/cosmos-dusk.v3.css +200 -0
- package/default-themes/high-contrast-dark.json +19 -0
- package/default-themes/high-contrast-dark.v3.css +200 -0
- package/default-themes/high-contrast-light.json +19 -0
- package/default-themes/high-contrast-light.v3.css +198 -0
- package/default-themes/{nebula-dawn.css → nebula-dawn.v2.css} +134 -0
- package/default-themes/nebula-dawn.v3.css +199 -0
- package/default-themes/{nebula-dusk.css → nebula-dusk.v2.css} +128 -0
- package/default-themes/nebula-dusk.v3.css +201 -0
- package/default-themes/solar-flare-dawn.json +19 -0
- package/default-themes/solar-flare-dawn.v3.css +198 -0
- package/default-themes/solar-flare-dusk.json +19 -0
- package/default-themes/solar-flare-dusk.v3.css +200 -0
- package/dist/agents/a2a/a2aProvider.d.ts.map +1 -0
- package/dist/agents/a2a/a2aProvider.js +126 -0
- package/dist/agents/a2a/a2aProvider.js.map +1 -0
- package/dist/agents/discovery.d.ts.map +1 -0
- package/dist/agents/discovery.js +52 -0
- package/dist/agents/discovery.js.map +1 -0
- package/dist/agents/index.d.ts +7 -0
- package/dist/agents/index.d.ts.map +1 -0
- package/dist/agents/index.js +20 -0
- package/dist/agents/index.js.map +1 -0
- package/dist/agents/openclaw/gatewayManager.d.ts +117 -0
- package/dist/agents/openclaw/gatewayManager.d.ts.map +1 -0
- package/dist/agents/openclaw/gatewayManager.js +486 -0
- package/dist/agents/openclaw/gatewayManager.js.map +1 -0
- package/dist/agents/openclaw/openclawProvider.d.ts.map +1 -0
- package/dist/agents/openclaw/openclawProvider.js +237 -0
- package/dist/agents/openclaw/openclawProvider.js.map +1 -0
- package/dist/agents/openclaw/sshTunnelManager.d.ts +25 -0
- package/dist/agents/openclaw/sshTunnelManager.d.ts.map +1 -0
- package/dist/agents/openclaw/sshTunnelManager.js +359 -0
- package/dist/agents/openclaw/sshTunnelManager.js.map +1 -0
- package/dist/agents/types.d.ts.map +1 -0
- package/dist/agents/types.js +6 -0
- package/dist/agents/types.js.map +1 -0
- package/dist/builders/anthropic.d.ts +31 -0
- package/dist/builders/anthropic.d.ts.map +1 -0
- package/dist/builders/anthropic.js +227 -0
- package/dist/builders/anthropic.js.map +1 -0
- package/dist/builders/fireworksai.d.ts +9 -0
- package/dist/builders/fireworksai.d.ts.map +1 -0
- package/dist/builders/fireworksai.js +57 -0
- package/dist/builders/fireworksai.js.map +1 -0
- package/dist/builders/index.d.ts +13 -0
- package/dist/builders/index.d.ts.map +1 -0
- package/dist/builders/index.js +31 -0
- package/dist/builders/index.js.map +1 -0
- package/dist/builders/openai.d.ts +8 -0
- package/dist/builders/openai.d.ts.map +1 -0
- package/dist/builders/openai.js +87 -0
- package/dist/builders/openai.js.map +1 -0
- package/dist/builders/types.d.ts +54 -0
- package/dist/builders/types.d.ts.map +1 -0
- package/dist/builders/types.js +211 -0
- package/dist/builders/types.js.map +1 -0
- package/dist/connectors/index.d.ts.map +1 -1
- package/dist/connectors/index.js +3 -2
- package/dist/connectors/index.js.map +1 -1
- package/dist/connectors/registry.d.ts +2 -1
- package/dist/connectors/registry.d.ts.map +1 -1
- package/dist/connectors/registry.js +65 -96
- package/dist/connectors/registry.js.map +1 -1
- package/dist/connectors/types.d.ts.map +1 -1
- package/dist/customizer/Customizer.d.ts +57 -0
- package/dist/customizer/Customizer.d.ts.map +1 -0
- package/dist/customizer/Customizer.js +124 -0
- package/dist/customizer/Customizer.js.map +1 -0
- package/dist/customizer/index.d.ts.map +1 -0
- package/dist/customizer/index.js +9 -0
- package/dist/customizer/index.js.map +1 -0
- package/dist/files.d.ts +17 -0
- package/dist/files.d.ts.map +1 -1
- package/dist/files.js +75 -1
- package/dist/files.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/init.d.ts +10 -6
- package/dist/init.d.ts.map +1 -1
- package/dist/init.js +97 -86
- package/dist/init.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +142 -145
- package/dist/migrations.js.map +1 -1
- package/dist/models/anthropic.d.ts +24 -0
- package/dist/models/anthropic.d.ts.map +1 -0
- package/dist/models/anthropic.js +103 -0
- package/dist/models/anthropic.js.map +1 -0
- package/dist/models/chainOfThought.d.ts.map +1 -0
- package/dist/models/chainOfThought.js +45 -0
- package/dist/models/chainOfThought.js.map +1 -0
- package/dist/models/fireworksai.d.ts.map +1 -0
- package/dist/models/fireworksai.js +141 -0
- package/dist/models/fireworksai.js.map +1 -0
- package/dist/models/index.d.ts +7 -1
- package/dist/models/index.d.ts.map +1 -1
- package/dist/models/index.js +20 -1
- package/dist/models/index.js.map +1 -1
- package/dist/models/logCompletePrompt.d.ts.map +1 -0
- package/dist/models/logCompletePrompt.js +23 -0
- package/dist/models/logCompletePrompt.js.map +1 -0
- package/dist/models/openai.d.ts +24 -0
- package/dist/models/openai.d.ts.map +1 -0
- package/dist/models/openai.js +101 -0
- package/dist/models/openai.js.map +1 -0
- package/dist/models/providers.d.ts.map +1 -1
- package/dist/models/providers.js +12 -4
- package/dist/models/providers.js.map +1 -1
- package/dist/models/types.d.ts +53 -2
- package/dist/models/types.d.ts.map +1 -1
- package/dist/models/types.js +21 -0
- package/dist/models/types.js.map +1 -1
- package/dist/models/utils.d.ts.map +1 -0
- package/dist/models/utils.js +21 -0
- package/dist/models/utils.js.map +1 -0
- package/dist/pages.d.ts +30 -7
- package/dist/pages.d.ts.map +1 -1
- package/dist/pages.js +177 -55
- package/dist/pages.js.map +1 -1
- package/dist/scripts.d.ts.map +1 -1
- package/dist/scripts.js +4 -3
- package/dist/scripts.js.map +1 -1
- package/dist/service/createCompletePrompt.d.ts.map +1 -1
- package/dist/service/createCompletePrompt.js +9 -6
- package/dist/service/createCompletePrompt.js.map +1 -1
- package/dist/service/generateImage.d.ts.map +1 -1
- package/dist/service/generateImage.js +3 -3
- package/dist/service/generateImage.js.map +1 -1
- package/dist/service/server.d.ts.map +1 -1
- package/dist/service/server.js +39 -7
- package/dist/service/server.js.map +1 -1
- package/dist/service/transformPage.d.ts +47 -18
- package/dist/service/transformPage.d.ts.map +1 -1
- package/dist/service/transformPage.js +559 -270
- package/dist/service/transformPage.js.map +1 -1
- package/dist/service/useAgentRoutes.d.ts +5 -0
- package/dist/service/useAgentRoutes.d.ts.map +1 -0
- package/dist/service/useAgentRoutes.js +392 -0
- package/dist/service/useAgentRoutes.js.map +1 -0
- package/dist/service/useApiRoutes.d.ts.map +1 -1
- package/dist/service/useApiRoutes.js +380 -138
- package/dist/service/useApiRoutes.js.map +1 -1
- package/dist/service/useConnectorRoutes.d.ts.map +1 -1
- package/dist/service/useConnectorRoutes.js +20 -9
- package/dist/service/useConnectorRoutes.js.map +1 -1
- package/dist/service/useFileRoutes.d.ts +4 -0
- package/dist/service/useFileRoutes.d.ts.map +1 -0
- package/dist/service/useFileRoutes.js +122 -0
- package/dist/service/useFileRoutes.js.map +1 -0
- package/dist/service/usePageRoutes.d.ts.map +1 -1
- package/dist/service/usePageRoutes.js +660 -68
- package/dist/service/usePageRoutes.js.map +1 -1
- package/dist/service/useSharedDataRoutes.d.ts +4 -0
- package/dist/service/useSharedDataRoutes.d.ts.map +1 -0
- package/dist/service/useSharedDataRoutes.js +104 -0
- package/dist/service/useSharedDataRoutes.js.map +1 -0
- package/dist/service/useSharedFileRoutes.d.ts +4 -0
- package/dist/service/useSharedFileRoutes.d.ts.map +1 -0
- package/dist/service/useSharedFileRoutes.js +121 -0
- package/dist/service/useSharedFileRoutes.js.map +1 -0
- package/dist/settings.d.ts +3 -1
- package/dist/settings.d.ts.map +1 -1
- package/dist/settings.js +5 -8
- package/dist/settings.js.map +1 -1
- package/dist/synthos-cli.d.ts.map +1 -1
- package/dist/synthos-cli.js +4 -3
- package/dist/synthos-cli.js.map +1 -1
- package/dist/themes.d.ts +15 -0
- package/dist/themes.d.ts.map +1 -1
- package/dist/themes.js +106 -20
- package/dist/themes.js.map +1 -1
- package/migration-rules/v1-to-v2.md +193 -0
- package/migration-rules/v2-to-v3.md +481 -0
- package/package.json +15 -11
- package/required-pages/builder/page.html +43 -0
- package/required-pages/builder/page.json +10 -0
- package/required-pages/pages/page.html +924 -0
- package/required-pages/pages/page.json +10 -0
- package/required-pages/settings/page.html +1753 -0
- package/required-pages/settings/page.json +10 -0
- package/required-pages/synthos_apis/page.html +846 -0
- package/required-pages/synthos_apis/page.json +10 -0
- package/required-pages/{synthos_scripts.html → synthos_scripts/page.html} +13 -11
- package/required-pages/synthos_scripts/page.json +10 -0
- package/service-connectors/airtable/connector.json +27 -0
- package/service-connectors/alpha-vantage/connector.json +26 -0
- package/service-connectors/brave-search/connector.json +26 -0
- package/service-connectors/cloudinary/connector.json +27 -0
- package/service-connectors/deepl/connector.json +28 -0
- package/service-connectors/elevenlabs/connector.json +30 -0
- package/service-connectors/giphy/connector.json +27 -0
- package/service-connectors/github/connector.json +29 -0
- package/service-connectors/huggingface/connector.json +27 -0
- package/service-connectors/imgur/connector.json +29 -0
- package/service-connectors/instagram/connector.json +43 -0
- package/service-connectors/jira/connector.json +28 -0
- package/service-connectors/mapbox/connector.json +26 -0
- package/service-connectors/nasa/connector.json +27 -0
- package/service-connectors/newsapi/connector.json +27 -0
- package/service-connectors/notion/connector.json +28 -0
- package/service-connectors/open-exchange-rates/connector.json +27 -0
- package/service-connectors/openweathermap/connector.json +26 -0
- package/service-connectors/pexels/connector.json +27 -0
- package/service-connectors/resend/connector.json +29 -0
- package/service-connectors/rss2json/connector.json +27 -0
- package/service-connectors/sendgrid/connector.json +27 -0
- package/service-connectors/spoonacular/connector.json +28 -0
- package/service-connectors/stability-ai/connector.json +27 -0
- package/service-connectors/twilio/connector.json +28 -0
- package/service-connectors/unsplash/connector.json +27 -0
- package/service-connectors/wolfram-alpha/connector.json +26 -0
- package/service-connectors/youtube-data/connector.json +30 -0
- package/src/agents/a2a/a2aProvider.ts +110 -0
- package/src/agents/discovery.ts +74 -0
- package/src/agents/index.ts +6 -0
- package/src/agents/openclaw/gatewayManager.ts +570 -0
- package/src/agents/openclaw/openclawProvider.ts +259 -0
- package/src/agents/openclaw/sshTunnelManager.ts +393 -0
- package/src/agents/types.ts +82 -0
- package/src/builders/anthropic.ts +283 -0
- package/src/builders/fireworksai.ts +59 -0
- package/src/builders/index.ts +33 -0
- package/src/builders/openai.ts +89 -0
- package/src/builders/types.ts +261 -0
- package/src/connectors/index.ts +3 -1
- package/src/connectors/registry.ts +40 -96
- package/src/connectors/types.ts +25 -0
- package/src/customizer/Customizer.ts +151 -0
- package/src/customizer/index.ts +5 -0
- package/src/files.ts +71 -0
- package/src/index.ts +2 -1
- package/src/init.ts +138 -97
- package/src/migrations.ts +148 -145
- package/src/models/anthropic.ts +119 -0
- package/src/models/chainOfThought.ts +56 -0
- package/src/models/fireworksai.ts +143 -0
- package/src/models/index.ts +7 -1
- package/src/models/logCompletePrompt.ts +25 -0
- package/src/models/openai.ts +110 -0
- package/src/models/providers.ts +12 -3
- package/src/models/types.ts +97 -2
- package/src/models/utils.ts +16 -0
- package/src/pages.ts +176 -54
- package/src/scripts.ts +2 -2
- package/src/service/createCompletePrompt.ts +3 -1
- package/src/service/generateImage.ts +2 -2
- package/src/service/server.ts +39 -8
- package/src/service/transformPage.ts +605 -301
- package/src/service/useAgentRoutes.ts +428 -0
- package/src/service/useApiRoutes.ts +309 -45
- package/src/service/useConnectorRoutes.ts +21 -10
- package/src/service/useFileRoutes.ts +127 -0
- package/src/service/usePageRoutes.ts +736 -75
- package/src/service/useSharedDataRoutes.ts +106 -0
- package/src/service/useSharedFileRoutes.ts +126 -0
- package/src/settings.ts +8 -10
- package/src/synthos-cli.ts +4 -3
- package/src/themes.ts +103 -20
- package/static-files/favicon.svg +12 -0
- package/static-files/fluentlm-instructions.llmd +868 -0
- package/static-files/fluentlm-instructions.md +1595 -0
- package/static-files/fluentlm.css +4844 -0
- package/static-files/fluentlm.js +3602 -0
- package/static-files/fluentlm.min.css +1 -0
- package/static-files/fluentlm.min.js +1 -0
- package/static-files/helpers.v3.js +304 -0
- package/static-files/page.v3.js +1290 -0
- package/static-files/recommended-frameworks.llmd +81 -0
- package/static-files/recommended-frameworks.md +137 -0
- package/static-files/retro-game.js +877 -0
- package/static-files/shell.css +797 -0
- package/static-files/theme-dark.css +169 -0
- package/static-files/theme-light.css +169 -0
- package/tests/anthropic.spec.ts +84 -0
- package/tests/builders.spec.ts +139 -0
- package/tests/chainOfThought.spec.ts +108 -0
- package/tests/ensureScripts.spec.ts +82 -0
- package/tests/files.spec.ts +233 -0
- package/tests/fireworksai.spec.ts +92 -0
- package/tests/logCompletePrompt.spec.ts +74 -0
- package/tests/migrations.spec.ts +79 -1
- package/tests/openai.spec.ts +71 -0
- package/tests/pages.spec.ts +226 -1
- package/tests/providers.spec.ts +144 -0
- package/tests/scripts.spec.ts +209 -0
- package/tests/transformPage.spec.ts +456 -0
- package/tests/types.spec.ts +23 -0
- package/default-pages/app_builder.html +0 -40
- package/default-pages/app_builder.json +0 -1
- package/default-pages/json_tools.json +0 -1
- package/default-pages/my_notes.html +0 -33
- package/default-pages/neon_asteroids.html +0 -77
- package/default-pages/sidebar_builder.json +0 -1
- package/default-pages/solar_tutorial.json +0 -1
- package/default-pages/two-panel_builder.json +0 -1
- package/dist/connectors/index.d.ts +0 -3
- package/dist/connectors/types.d.ts +0 -61
- package/dist/index.d.ts +0 -7
- package/dist/migrations.d.ts +0 -11
- package/dist/models/providers.d.ts +0 -7
- package/dist/scripts.d.ts +0 -14
- package/dist/service/createCompletePrompt.d.ts +0 -5
- package/dist/service/debugLog.d.ts +0 -11
- package/dist/service/generateImage.d.ts +0 -32
- package/dist/service/index.d.ts +0 -8
- package/dist/service/modelInstructions.d.ts +0 -7
- package/dist/service/requiresSettings.d.ts +0 -3
- package/dist/service/server.d.ts +0 -4
- package/dist/service/useApiRoutes.d.ts +0 -4
- package/dist/service/useConnectorRoutes.d.ts +0 -4
- package/dist/service/useDataRoutes.d.ts +0 -4
- package/dist/service/usePageRoutes.d.ts +0 -5
- package/dist/synthos-cli.d.ts +0 -2
- package/images/home.png +0 -0
- package/images/page-management.png +0 -0
- package/images/settings.png +0 -0
- package/images/synthos-square.png +0 -0
- package/page-scripts/helpers-v2.js +0 -121
- package/page-scripts/page-v2.js +0 -615
- package/required-pages/builder.html +0 -74
- package/required-pages/builder.json +0 -1
- package/required-pages/pages.html +0 -196
- package/required-pages/pages.json +0 -1
- package/required-pages/settings.html +0 -841
- package/required-pages/settings.json +0 -1
- package/required-pages/synthos_apis.html +0 -272
- package/required-pages/synthos_apis.json +0 -1
- package/required-pages/synthos_scripts.json +0 -1
|
@@ -1,841 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="en"><head>
|
|
2
|
-
<meta charset="UTF-8">
|
|
3
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
4
|
-
<title>SynthOS - Settings</title>
|
|
5
|
-
<script id="theme-info" src="/api/theme-info.js" data-locked="true"></script>
|
|
6
|
-
<link id="theme-css" rel="stylesheet" href="/api/theme.css" data-locked="true">
|
|
7
|
-
<style>.settings-title{font-size:22px;font-weight:700;min-height:var(--header-min-height);padding:var(--header-padding-vertical) var(--header-padding-horizontal);line-height:var(--header-line-height);display:flex;align-items:center;justify-content:center;box-sizing:border-box;background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;border-radius:12px 12px 0 0;width:100%;box-shadow:0 6px 25px var(--accent-glow);letter-spacing:2px;text-shadow:0 2px 10px rgba(0,0,0,.3)}.settings-container{display:flex;flex-direction:column;width:100%;flex-grow:1;background:rgba(15,15,35,.8);border-radius:0 0 12px 12px;border:1px solid rgba(138,43,226,.2);border-top:none;overflow:hidden}.accordion-section{display:flex;flex-direction:column;flex-shrink:0;overflow:hidden;border-bottom:1px solid var(--border-color)}.accordion-section:last-child{border-bottom:none}.accordion-section.active{flex-shrink:1;flex-grow:1;min-height:0}.accordion-header{display:flex;justify-content:space-between;align-items:center;width:100%;padding:16px 25px;background:none;border:none;color:var(--text-primary);font-size:15px;font-weight:600;cursor:pointer;transition:background .3s;letter-spacing:.5px;flex-shrink:0}.accordion-header:hover{background:rgba(138,43,226,.05)}.accordion-section.active .accordion-header{background:rgba(138,43,226,.08)}.accordion-chevron{font-size:11px;color:var(--text-secondary);transition:transform .3s}.accordion-section.active .accordion-chevron{transform:rotate(180deg)}.accordion-body{display:none;flex-direction:column;flex-grow:1;min-height:0;overflow:hidden}.accordion-section.active .accordion-body{display:flex}.accordion-content{display:flex;flex-direction:column;gap:15px;overflow-y:auto;padding:20px 25px;flex-grow:1}.button-row{display:flex;justify-content:flex-end;padding:15px 25px;border-top:1px solid var(--border-color);flex-shrink:0}.apply-btn{padding:12px 30px;border:none;border-radius:12px;font-size:15px;background:linear-gradient(135deg,var(--accent-primary) 0,var(--accent-secondary) 50%,var(--accent-tertiary) 100%);color:#fff;cursor:pointer;transition:.3s;font-weight:600;letter-spacing:1px;box-shadow:0 4px 20px rgba(102,126,234,.4)}.apply-btn:hover{transform:translateY(-2px);box-shadow:0 6px 25px rgba(102,126,234,.6)}.apply-btn:active{transform:translateY(0)}.form-group{display:flex;flex-direction:column;width:100%}.form-group label{display:block;margin-bottom:8px;color:var(--text-secondary);font-weight:600;font-size:14px}.form-group input,.form-group select,.form-group textarea{width:100%;padding:14px 18px;border-radius:12px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:14px;transition:.3s;box-shadow:inset 0 2px 10px rgba(0,0,0,.3)}.form-group input:focus,.form-group select:focus,.form-group textarea:focus{outline:0;border-color:rgba(183,148,246,.6);box-shadow:inset 0 2px 10px rgba(0,0,0,.3),0 0 20px var(--accent-glow)}.form-group input::placeholder,.form-group textarea::placeholder{color:rgba(183,148,246,.5)}.form-group textarea{resize:vertical;min-height:100px}.form-group select{cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath fill='%23b794f6' d='M6 8L1 3h10z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 15px center}.form-group select option{background:var(--bg-tertiary);color:var(--text-primary);padding:10px}.info-text{color:rgba(183,148,246,.7);font-size:13px;line-height:1.6;text-align:center;padding:15px;background:rgba(15,15,35,.4);border-radius:10px;border:1px solid var(--border-color)}.info-text a{color:var(--accent-tertiary);text-decoration:none;transition:.3s;font-weight:500}.info-text a:hover{color:var(--text-secondary);text-shadow:0 0 10px var(--accent-glow)}.config-required-banner{padding:12px 20px;background:rgba(255,180,50,.12);border:1px solid rgba(255,180,50,.3);border-radius:10px;color:rgba(255,200,100,.9);font-size:13px;font-weight:500;text-align:center;line-height:1.5}.model-card{border:1px solid var(--border-color);border-radius:12px;padding:18px;display:flex;flex-direction:column;gap:12px;background:rgba(15,15,35,.3)}.model-card-title{font-size:14px;font-weight:700;color:var(--text-primary);letter-spacing:.5px;margin:0}.filter-bar{display:flex;align-items:center;gap:8px;flex-wrap:nowrap}.filter-btn{padding:6px 14px;border-radius:20px;border:1px solid var(--border-color);background:0 0;color:var(--text-secondary);font-size:13px;cursor:pointer;transition:.2s;white-space:nowrap;flex-shrink:0}.filter-btn:hover{border-color:var(--accent-primary);color:var(--accent-primary)}.filter-btn.active{background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary));color:#fff;border-color:transparent}.services-grid{display:grid;grid-template-columns:1fr;gap:12px}.service-card{border-radius:12px;border:1px solid var(--border-color);background:rgba(15,15,35,.5);padding:18px;transition:.3s}.service-card:hover{border-color:rgba(138,43,226,.3)}.service-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px}.service-card-name{font-size:15px;font-weight:600;color:var(--text-primary)}.service-card-category{font-size:11px;color:var(--text-secondary);background:rgba(138,43,226,.15);padding:2px 8px;border-radius:10px}.service-card-desc{font-size:13px;color:var(--text-secondary);line-height:1.5;margin-bottom:12px}.service-card-fields{display:flex;flex-direction:column;gap:8px}.service-card-fields input{width:100%;padding:10px 14px;border-radius:8px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:13px;transition:.3s;box-shadow:inset 0 2px 8px rgba(0,0,0,.2)}.service-card-fields input:focus{outline:0;border-color:rgba(183,148,246,.6);box-shadow:inset 0 2px 8px rgba(0,0,0,.2),0 0 15px var(--accent-glow)}.service-card-fields input::placeholder{color:rgba(183,148,246,.5)}.toggle-switch{position:relative;width:44px;height:24px;flex-shrink:0}.toggle-switch input{opacity:0;width:0;height:0}.toggle-slider{position:absolute;cursor:pointer;top:0;left:0;right:0;bottom:0;background:rgba(100,100,100,.4);border-radius:24px;transition:.3s}.toggle-slider:before{content:"";position:absolute;height:18px;width:18px;left:3px;bottom:3px;background:#fff;border-radius:50%;transition:.3s}.toggle-switch input:checked+.toggle-slider{background:linear-gradient(135deg,var(--accent-primary),var(--accent-secondary))}.toggle-switch input:checked+.toggle-slider:before{transform:translateX(20px)}.light-mode .settings-container{background:rgba(255,255,255,.8)}.light-mode .accordion-header:hover{background:rgba(118,75,162,.05)}.light-mode .accordion-section.active .accordion-header{background:rgba(118,75,162,.06)}.light-mode .form-group input,.light-mode .form-group select,.light-mode .form-group textarea{background:rgba(255,255,255,.8);box-shadow:inset 0 2px 10px rgba(118,75,162,.05)}.light-mode .form-group input:focus,.light-mode .form-group select:focus,.light-mode .form-group textarea:focus{box-shadow:inset 0 2px 10px rgba(118,75,162,.05),0 0 20px var(--accent-glow)}.light-mode .form-group input::placeholder,.light-mode .form-group textarea::placeholder{color:rgba(107,79,138,.5)}.light-mode .info-text{color:rgba(107,79,138,.7);background:rgba(255,255,255,.4)}.light-mode .config-required-banner{background:rgba(200,150,50,.1);border-color:rgba(200,150,50,.3);color:rgba(160,120,30,.9)}.light-mode .model-card{background:rgba(255,255,255,.3)}.light-mode .service-card{background:rgba(255,255,255,.5)}.light-mode .service-card-fields input{background:rgba(255,255,255,.8);box-shadow:inset 0 2px 8px rgba(118,75,162,.05)}.light-mode .service-card-fields input:focus{box-shadow:inset 0 2px 8px rgba(118,75,162,.05),0 0 15px var(--accent-glow)}.light-mode .service-card-fields input::placeholder{color:rgba(107,79,138,.5)}.model-card.disabled{opacity:0.35;pointer-events:none;user-select:none;transition:opacity .3s}.wizard-hidden{display:none !important}.more-settings-link{display:inline-block;color:var(--accent-tertiary);font-size:13px;cursor:pointer;text-decoration:none;padding:4px 0;transition:.3s;user-select:none}.more-settings-link:hover{color:var(--text-secondary);text-shadow:0 0 10px var(--accent-glow)}.light-mode .model-card.disabled{opacity:0.35}.accordion-section.disabled .accordion-header{opacity:0.35;pointer-events:none;cursor:default}.apply-btn:disabled{opacity:0.35;pointer-events:none;cursor:default}.connector-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(140px,1fr));gap:12px}.connector-tile{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:20px 12px;border-radius:14px;border:1px solid var(--border-color);background:linear-gradient(160deg,rgba(30,30,60,.6),rgba(20,20,50,.8));cursor:pointer;transition:transform .2s,box-shadow .2s,border-color .2s;gap:8px}.connector-tile:hover{transform:translateY(-3px);box-shadow:0 6px 20px var(--accent-glow);border-color:var(--accent-primary)}.connector-tile.configured{background:linear-gradient(160deg,rgba(60,30,90,.6),rgba(40,20,70,.8));border-color:var(--accent-secondary);box-shadow:0 2px 12px var(--accent-glow)}.connector-tile-name{font-size:14px;font-weight:600;color:var(--text-primary)}.connector-category{font-size:11px;color:var(--text-secondary);background:rgba(138,43,226,.15);padding:2px 8px;border-radius:10px}.search-input{flex:1;min-width:100px;padding:6px 14px;border-radius:20px;border:1px solid var(--border-color);background:rgba(15,15,35,.8);color:var(--text-primary);font-size:13px;transition:.3s}.search-input:focus{outline:0;border-color:rgba(183,148,246,.6)}.search-input::placeholder{color:rgba(183,148,246,.5)}.filter-buttons-container{display:flex;gap:8px;flex-wrap:nowrap}.conn-modal-overlay{position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,.6);display:flex;align-items:center;justify-content:center;z-index:1000}.conn-modal-content{background:rgba(20,20,50,.95);border:1px solid var(--border-color);border-radius:16px;padding:28px;max-width:420px;width:90%;display:flex;flex-direction:column;gap:16px;box-shadow:0 8px 40px rgba(0,0,0,.5)}.conn-modal-title{font-size:18px;font-weight:700;color:var(--text-primary)}.conn-modal-desc{font-size:13px;color:var(--text-secondary);line-height:1.5}.conn-modal-actions{display:flex;gap:10px;justify-content:flex-end;margin-top:8px}.conn-modal-btn{padding:12px 24px;border:none;border-radius:12px;font-size:14px;background:linear-gradient(135deg,var(--accent-primary) 0,var(--accent-secondary) 50%,var(--accent-tertiary) 100%);color:#fff;cursor:pointer;transition:.3s;font-weight:600;letter-spacing:.5px;box-shadow:0 4px 20px rgba(102,126,234,.4)}.conn-modal-btn:hover{transform:translateY(-2px);box-shadow:0 6px 25px rgba(102,126,234,.6)}.conn-modal-btn.cancel{background:rgba(100,100,100,.4);box-shadow:none}.conn-modal-btn.cancel:hover{background:rgba(100,100,100,.6);transform:translateY(-1px)}.conn-modal-btn.remove{background:rgba(180,50,50,.6);box-shadow:none}.conn-modal-btn.remove:hover{background:rgba(200,60,60,.8);transform:translateY(-1px)}.light-mode .connector-tile{background:linear-gradient(160deg,rgba(240,235,255,.8),rgba(250,248,255,.9))}.light-mode .connector-tile.configured{background:linear-gradient(160deg,rgba(220,200,255,.8),rgba(235,220,255,.9))}.light-mode .search-input{background:rgba(255,255,255,.8)}.light-mode .search-input::placeholder{color:rgba(107,79,138,.5)}.light-mode .conn-modal-content{background:rgba(250,248,255,.98)}</style>
|
|
8
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/7.9.0/d3.min.js"></script>
|
|
9
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/marked/14.1.1/marked.min.js"></script>
|
|
10
|
-
<script src="https://cdnjs.cloudflare.com/ajax/libs/mermaid/11.1.0/mermaid.min.js"></script>
|
|
11
|
-
</head>
|
|
12
|
-
<body>
|
|
13
|
-
<div class="chat-panel" data-locked="true">
|
|
14
|
-
<div class="chat-header" data-locked="true">SynthOS</div>
|
|
15
|
-
<div class="chat-messages" id="chatMessages" data-locked="true">
|
|
16
|
-
<div class="chat-message" id="defaultGreeting">
|
|
17
|
-
<p><strong>SynthOS:</strong> Configure your settings below. Use the accordion sections to navigate between General settings, Model configuration (Page Builder & Chat Completion), and Additional Features.</p>
|
|
18
|
-
<p>The <strong>Page Builder Model</strong> is used when building pages via chat. The <strong>Chat Model</strong> is used by pages that call <code>synthos.generate.completion()</code>.</p>
|
|
19
|
-
</div>
|
|
20
|
-
<div class="chat-message" id="firstRunGreeting" style="display:none;">
|
|
21
|
-
<p><strong>SynthOS:</strong> Welcome to SynthOS! We're glad you're here.</p>
|
|
22
|
-
<p>Before you can start building, we need to connect to an AI provider. Just pick your provider below, paste in your API key, and you'll be ready to go.</p>
|
|
23
|
-
<p>You can always come back to this page later to change your theme or enable additional features.</p>
|
|
24
|
-
</div>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="link-group" data-locked="true">
|
|
27
|
-
<a href="#" id="saveLink" data-locked="true">Save</a>
|
|
28
|
-
<a href="/pages" id="pagesLink" data-locked="true">Pages</a>
|
|
29
|
-
<a href="#" id="resetLink" data-locked="true">Reset</a>
|
|
30
|
-
</div>
|
|
31
|
-
<form action="/" method="POST" id="chatForm" data-locked="true">
|
|
32
|
-
<input type="text" class="chat-input" id="chatInput" name="message" placeholder="Type a message..." data-locked="true">
|
|
33
|
-
<button type="submit" class="chat-submit" data-locked="true">Send</button>
|
|
34
|
-
</form>
|
|
35
|
-
</div>
|
|
36
|
-
<div class="viewer-panel" id="viewerPanel" style="justify-content: flex-start; align-items: stretch;">
|
|
37
|
-
<div class="settings-title" style="max-width: none; border-radius: 12px 12px 0 0;">Settings</div>
|
|
38
|
-
<div class="settings-container" style="max-width: none; border-radius: 0; max-height: none; flex-grow: 1;">
|
|
39
|
-
|
|
40
|
-
<div class="accordion-section active" data-section="general">
|
|
41
|
-
<button class="accordion-header">
|
|
42
|
-
<span>General</span>
|
|
43
|
-
<span class="accordion-chevron">▾</span>
|
|
44
|
-
</button>
|
|
45
|
-
<div class="accordion-body">
|
|
46
|
-
<div class="accordion-content">
|
|
47
|
-
<div class="form-group">
|
|
48
|
-
<label for="theme">Theme</label>
|
|
49
|
-
<select id="theme">
|
|
50
|
-
<option value="">Loading themes...</option>
|
|
51
|
-
</select>
|
|
52
|
-
</div>
|
|
53
|
-
</div>
|
|
54
|
-
<div class="button-row">
|
|
55
|
-
<button class="apply-btn" data-apply="general">Apply</button>
|
|
56
|
-
</div>
|
|
57
|
-
</div>
|
|
58
|
-
</div>
|
|
59
|
-
|
|
60
|
-
<div class="accordion-section" data-section="models">
|
|
61
|
-
<button class="accordion-header">
|
|
62
|
-
<span>Page Building & Chat</span>
|
|
63
|
-
<span class="accordion-chevron">▾</span>
|
|
64
|
-
</button>
|
|
65
|
-
<div class="accordion-body">
|
|
66
|
-
<div class="accordion-content">
|
|
67
|
-
<div id="configBanner" class="config-required-banner" style="display:none;">
|
|
68
|
-
Model configuration is required before you can use SynthOS. Please fill in the Page Builder fields below and click Apply.
|
|
69
|
-
</div>
|
|
70
|
-
|
|
71
|
-
<div class="model-card" id="builderCard">
|
|
72
|
-
<div class="model-card-title">Page Builder Model</div>
|
|
73
|
-
<div class="form-group">
|
|
74
|
-
<label for="provider-builder">Provider</label>
|
|
75
|
-
<select id="provider-builder" required="">
|
|
76
|
-
<option value="">Select a provider</option>
|
|
77
|
-
</select>
|
|
78
|
-
</div>
|
|
79
|
-
<div class="form-group" id="fg-apikey-builder">
|
|
80
|
-
<label for="serviceApiKey-builder">API Key</label>
|
|
81
|
-
<input type="password" id="serviceApiKey-builder" placeholder="Enter your API Key" required="">
|
|
82
|
-
<div id="providerInstructions" class="info-text" style="display:none;margin-top:8px;"></div>
|
|
83
|
-
</div>
|
|
84
|
-
<div class="form-group" id="fg-model-builder">
|
|
85
|
-
<label for="model-builder">Model</label>
|
|
86
|
-
<select id="model-builder" required="">
|
|
87
|
-
<option value="">Select a model</option>
|
|
88
|
-
</select>
|
|
89
|
-
</div>
|
|
90
|
-
<a id="moreSettingsLink" class="more-settings-link">▾ More settings</a>
|
|
91
|
-
<div class="form-group" id="fg-maxTokens-builder">
|
|
92
|
-
<label for="maxTokens-builder">Max Output Tokens</label>
|
|
93
|
-
<input type="number" id="maxTokens-builder" placeholder="Enter max token count" required="">
|
|
94
|
-
</div>
|
|
95
|
-
<div class="form-group" id="fg-instructions-builder">
|
|
96
|
-
<label for="instructions-builder">Additional Instructions</label>
|
|
97
|
-
<textarea id="instructions-builder" placeholder="Enter any additional instructions"></textarea>
|
|
98
|
-
</div>
|
|
99
|
-
</div>
|
|
100
|
-
|
|
101
|
-
<div class="model-card" id="chatCard">
|
|
102
|
-
<div class="model-card-title">Chat Model</div>
|
|
103
|
-
<div class="form-group" id="fg-provider-chat">
|
|
104
|
-
<label for="provider-chat">Provider</label>
|
|
105
|
-
<select id="provider-chat" required="">
|
|
106
|
-
<option value="">Select a provider</option>
|
|
107
|
-
</select>
|
|
108
|
-
</div>
|
|
109
|
-
<div class="form-group" id="fg-apikey-chat">
|
|
110
|
-
<label for="serviceApiKey-chat">API Key</label>
|
|
111
|
-
<input type="password" id="serviceApiKey-chat" placeholder="Enter your API Key" required="">
|
|
112
|
-
</div>
|
|
113
|
-
<div class="form-group" id="fg-model-chat">
|
|
114
|
-
<label for="model-chat">Model</label>
|
|
115
|
-
<select id="model-chat" required="">
|
|
116
|
-
<option value="">Select a model</option>
|
|
117
|
-
</select>
|
|
118
|
-
</div>
|
|
119
|
-
<a id="moreSettingsLinkChat" class="more-settings-link">▾ More settings</a>
|
|
120
|
-
<div class="form-group" id="fg-maxTokens-chat">
|
|
121
|
-
<label for="maxTokens-chat">Max Output Tokens</label>
|
|
122
|
-
<input type="number" id="maxTokens-chat" placeholder="Enter max token count" required="">
|
|
123
|
-
</div>
|
|
124
|
-
<div class="form-group" id="fg-instructions-chat">
|
|
125
|
-
<label for="instructions-chat">Additional Instructions</label>
|
|
126
|
-
<textarea id="instructions-chat" placeholder="Enter any additional instructions"></textarea>
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
|
|
130
|
-
</div>
|
|
131
|
-
<div class="button-row">
|
|
132
|
-
<button class="apply-btn" data-apply="models">Apply</button>
|
|
133
|
-
</div>
|
|
134
|
-
</div>
|
|
135
|
-
</div>
|
|
136
|
-
|
|
137
|
-
<div class="accordion-section" data-section="connectors">
|
|
138
|
-
<button class="accordion-header">
|
|
139
|
-
<span>Connectors</span>
|
|
140
|
-
<span class="accordion-chevron">▾</span>
|
|
141
|
-
</button>
|
|
142
|
-
<div class="accordion-body">
|
|
143
|
-
<div class="accordion-content">
|
|
144
|
-
<div class="filter-bar" id="connectorFilterBar">
|
|
145
|
-
<div class="filter-buttons-container" id="connectorFilterButtons"></div>
|
|
146
|
-
<input type="text" class="search-input" id="connectorSearch" placeholder="Search connectors...">
|
|
147
|
-
</div>
|
|
148
|
-
<div class="connector-grid" id="connectorGrid"></div>
|
|
149
|
-
</div>
|
|
150
|
-
</div>
|
|
151
|
-
</div>
|
|
152
|
-
|
|
153
|
-
</div>
|
|
154
|
-
<div id="loadingOverlay" class="loading-overlay"><div class="spinner"></div></div>
|
|
155
|
-
</div>
|
|
156
|
-
<div class="conn-modal-overlay" id="connectorModal" style="display:none;">
|
|
157
|
-
<div class="conn-modal-content">
|
|
158
|
-
<div class="conn-modal-title" id="connectorModalTitle"></div>
|
|
159
|
-
<div class="conn-modal-desc" id="connectorModalDesc"></div>
|
|
160
|
-
<div id="connectorApiKeyGroup" class="form-group">
|
|
161
|
-
<label for="connectorApiKey">API Key</label>
|
|
162
|
-
<input type="password" id="connectorApiKey" placeholder="Enter your API key">
|
|
163
|
-
</div>
|
|
164
|
-
<div id="connectorOAuthGroup" style="display:none;">
|
|
165
|
-
<div id="connectorOAuthStatus" style="margin-bottom:12px;font-size:13px;line-height:1.5;"></div>
|
|
166
|
-
<div id="connectorOAuthModeToggle" style="display:flex;gap:8px;margin-bottom:12px;">
|
|
167
|
-
<button class="filter-btn active" id="oauthModeManual">Manual Token</button>
|
|
168
|
-
<button class="filter-btn" id="oauthModeApp">OAuth App</button>
|
|
169
|
-
</div>
|
|
170
|
-
<div id="connectorManualGroup">
|
|
171
|
-
<div class="form-group" style="margin-bottom:10px;">
|
|
172
|
-
<label for="oauth-field-accessToken">Access Token</label>
|
|
173
|
-
<input type="password" id="oauth-field-accessToken" placeholder="Paste token from Graph API Explorer">
|
|
174
|
-
</div>
|
|
175
|
-
<div class="form-group" style="margin-bottom:10px;">
|
|
176
|
-
<label for="oauth-field-userId">IG User ID <span style="color:var(--text-secondary);font-weight:400;">(optional)</span></label>
|
|
177
|
-
<input type="text" id="oauth-field-userId" placeholder="Instagram Business Account ID">
|
|
178
|
-
</div>
|
|
179
|
-
</div>
|
|
180
|
-
<div id="connectorAppGroup" style="display:none;">
|
|
181
|
-
<div class="form-group" id="connectorOAuthFields"></div>
|
|
182
|
-
<button class="conn-modal-btn" id="connectorConnectBtn" style="width:100%;margin-bottom:8px;">Connect with OAuth</button>
|
|
183
|
-
</div>
|
|
184
|
-
<button class="conn-modal-btn remove" id="connectorDisconnectBtn" style="width:100%;display:none;">Disconnect</button>
|
|
185
|
-
</div>
|
|
186
|
-
<div class="form-group" style="flex-direction:row;align-items:center;gap:12px;">
|
|
187
|
-
<label for="connectorEnabled" style="margin-bottom:0;">Enabled</label>
|
|
188
|
-
<label class="toggle-switch">
|
|
189
|
-
<input type="checkbox" id="connectorEnabled">
|
|
190
|
-
<span class="toggle-slider"></span>
|
|
191
|
-
</label>
|
|
192
|
-
</div>
|
|
193
|
-
<div class="conn-modal-actions">
|
|
194
|
-
<button class="conn-modal-btn" id="connectorSaveBtn">Save</button>
|
|
195
|
-
<button class="conn-modal-btn cancel" id="connectorCancelBtn">Cancel</button>
|
|
196
|
-
<button class="conn-modal-btn remove" id="connectorRemoveBtn">Remove</button>
|
|
197
|
-
</div>
|
|
198
|
-
</div>
|
|
199
|
-
</div>
|
|
200
|
-
<div id="instructionsHidden" style="display: none;" data-locked="true"></div>
|
|
201
|
-
<div id="thoughts" style="display: none;" data-locked="true"></div>
|
|
202
|
-
<script id="settings-logic">
|
|
203
|
-
// --- Accordion logic ---
|
|
204
|
-
function openSection(sectionName) {
|
|
205
|
-
document.querySelectorAll('.accordion-section').forEach(function(s) {
|
|
206
|
-
s.classList.remove('active');
|
|
207
|
-
});
|
|
208
|
-
var target = document.querySelector('.accordion-section[data-section="' + sectionName + '"]');
|
|
209
|
-
if (target) target.classList.add('active');
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
document.querySelectorAll('.accordion-header').forEach(function(header) {
|
|
213
|
-
header.addEventListener('click', function() {
|
|
214
|
-
var section = header.closest('.accordion-section');
|
|
215
|
-
if (section.classList.contains('disabled')) return;
|
|
216
|
-
var sectionName = section.dataset.section;
|
|
217
|
-
var isActive = section.classList.contains('active');
|
|
218
|
-
document.querySelectorAll('.accordion-section').forEach(function(s) {
|
|
219
|
-
s.classList.remove('active');
|
|
220
|
-
});
|
|
221
|
-
if (!isActive) {
|
|
222
|
-
section.classList.add('active');
|
|
223
|
-
// Update URL without reload
|
|
224
|
-
var url = new URL(window.location);
|
|
225
|
-
url.searchParams.set('tab', sectionName);
|
|
226
|
-
history.replaceState(null, '', url);
|
|
227
|
-
}
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
// --- URL param: open requested tab ---
|
|
232
|
-
var params = new URLSearchParams(window.location.search);
|
|
233
|
-
var tabParam = params.get('tab');
|
|
234
|
-
if (tabParam && ['general', 'models', 'connectors'].indexOf(tabParam) !== -1) {
|
|
235
|
-
openSection(tabParam);
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// --- Connectors logic ---
|
|
239
|
-
var connectorList = [], activeConnectorCategory = 'All', currentConnectorId = null;
|
|
240
|
-
|
|
241
|
-
function loadConnectors() {
|
|
242
|
-
fetch('/api/connectors').then(function(r) { return r.json(); }).then(function(list) {
|
|
243
|
-
connectorList = list;
|
|
244
|
-
renderConnectorFilterBar();
|
|
245
|
-
renderConnectorGrid();
|
|
246
|
-
});
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
function renderConnectorFilterBar() {
|
|
250
|
-
var container = document.getElementById('connectorFilterButtons');
|
|
251
|
-
container.innerHTML = '';
|
|
252
|
-
var cats = new Set();
|
|
253
|
-
connectorList.forEach(function(c) { cats.add(c.category); });
|
|
254
|
-
var sorted = Array.from(cats).sort();
|
|
255
|
-
['All'].concat(sorted).forEach(function(cat) {
|
|
256
|
-
var btn = document.createElement('button');
|
|
257
|
-
btn.className = 'filter-btn' + (activeConnectorCategory === cat ? ' active' : '');
|
|
258
|
-
btn.textContent = cat;
|
|
259
|
-
btn.addEventListener('click', function() {
|
|
260
|
-
activeConnectorCategory = cat;
|
|
261
|
-
renderConnectorFilterBar();
|
|
262
|
-
renderConnectorGrid();
|
|
263
|
-
});
|
|
264
|
-
container.appendChild(btn);
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
|
|
268
|
-
function renderConnectorGrid() {
|
|
269
|
-
var grid = document.getElementById('connectorGrid');
|
|
270
|
-
var searchTerm = (document.getElementById('connectorSearch').value || '').toLowerCase();
|
|
271
|
-
grid.innerHTML = '';
|
|
272
|
-
connectorList.filter(function(c) {
|
|
273
|
-
if (activeConnectorCategory !== 'All' && c.category !== activeConnectorCategory) return false;
|
|
274
|
-
if (searchTerm && c.name.toLowerCase().indexOf(searchTerm) === -1) return false;
|
|
275
|
-
return true;
|
|
276
|
-
}).forEach(function(c) {
|
|
277
|
-
var tile = document.createElement('div');
|
|
278
|
-
tile.className = 'connector-tile' + (c.configured ? ' configured' : '');
|
|
279
|
-
tile.addEventListener('click', function() { openConnectorModal(c.id); });
|
|
280
|
-
|
|
281
|
-
var name = document.createElement('div');
|
|
282
|
-
name.className = 'connector-tile-name';
|
|
283
|
-
name.textContent = c.name;
|
|
284
|
-
|
|
285
|
-
var cat = document.createElement('div');
|
|
286
|
-
cat.className = 'connector-category';
|
|
287
|
-
cat.textContent = c.category;
|
|
288
|
-
|
|
289
|
-
tile.appendChild(name);
|
|
290
|
-
tile.appendChild(cat);
|
|
291
|
-
grid.appendChild(tile);
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
var currentConnectorDetail = null;
|
|
296
|
-
|
|
297
|
-
function openConnectorModal(id) {
|
|
298
|
-
currentConnectorId = id;
|
|
299
|
-
fetch('/api/connectors/' + encodeURIComponent(id)).then(function(r) { return r.json(); }).then(function(detail) {
|
|
300
|
-
currentConnectorDetail = detail;
|
|
301
|
-
document.getElementById('connectorModalTitle').textContent = detail.name;
|
|
302
|
-
document.getElementById('connectorModalDesc').textContent = detail.description;
|
|
303
|
-
document.getElementById('connectorEnabled').checked = detail.enabled;
|
|
304
|
-
document.getElementById('connectorRemoveBtn').style.display = (detail.configured || detail.hasKey) ? '' : 'none';
|
|
305
|
-
|
|
306
|
-
var isOAuth = detail.authStrategy === 'oauth2';
|
|
307
|
-
document.getElementById('connectorApiKeyGroup').style.display = isOAuth ? 'none' : '';
|
|
308
|
-
document.getElementById('connectorOAuthGroup').style.display = isOAuth ? '' : 'none';
|
|
309
|
-
|
|
310
|
-
if (isOAuth) {
|
|
311
|
-
// Render OAuth App fields (App ID, App Secret)
|
|
312
|
-
var fieldsContainer = document.getElementById('connectorOAuthFields');
|
|
313
|
-
fieldsContainer.innerHTML = '';
|
|
314
|
-
(detail.fields || []).forEach(function(f) {
|
|
315
|
-
var wrap = document.createElement('div');
|
|
316
|
-
wrap.className = 'form-group';
|
|
317
|
-
wrap.style.marginBottom = '10px';
|
|
318
|
-
var lbl = document.createElement('label');
|
|
319
|
-
lbl.textContent = f.label;
|
|
320
|
-
lbl.setAttribute('for', 'oauth-field-' + f.name);
|
|
321
|
-
var inp = document.createElement('input');
|
|
322
|
-
inp.type = f.type;
|
|
323
|
-
inp.id = 'oauth-field-' + f.name;
|
|
324
|
-
inp.placeholder = detail.hasKey ? '(saved — leave blank to keep)' : 'Enter ' + f.label;
|
|
325
|
-
wrap.appendChild(lbl);
|
|
326
|
-
wrap.appendChild(inp);
|
|
327
|
-
fieldsContainer.appendChild(wrap);
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
// Reset manual token fields
|
|
331
|
-
document.getElementById('oauth-field-accessToken').value = '';
|
|
332
|
-
document.getElementById('oauth-field-accessToken').placeholder = detail.connected ? '(token saved — leave blank to keep)' : 'Paste token from Graph API Explorer';
|
|
333
|
-
document.getElementById('oauth-field-userId').value = '';
|
|
334
|
-
document.getElementById('oauth-field-userId').placeholder = detail.connected ? (detail.accountName || 'Instagram Business Account ID') : 'Instagram Business Account ID';
|
|
335
|
-
|
|
336
|
-
// Default to manual mode
|
|
337
|
-
setOAuthMode('manual');
|
|
338
|
-
|
|
339
|
-
// Show connected status
|
|
340
|
-
var statusEl = document.getElementById('connectorOAuthStatus');
|
|
341
|
-
var disconnectBtn = document.getElementById('connectorDisconnectBtn');
|
|
342
|
-
var modeToggle = document.getElementById('connectorOAuthModeToggle');
|
|
343
|
-
if (detail.connected) {
|
|
344
|
-
var displayName = detail.accountName || detail.name;
|
|
345
|
-
statusEl.innerHTML = '<span style="color:var(--accent-tertiary);">Connected as <strong>' + displayName + '</strong></span>';
|
|
346
|
-
statusEl.style.display = '';
|
|
347
|
-
disconnectBtn.style.display = '';
|
|
348
|
-
modeToggle.style.display = 'none';
|
|
349
|
-
} else {
|
|
350
|
-
statusEl.innerHTML = '';
|
|
351
|
-
statusEl.style.display = 'none';
|
|
352
|
-
disconnectBtn.style.display = 'none';
|
|
353
|
-
modeToggle.style.display = 'flex';
|
|
354
|
-
}
|
|
355
|
-
} else {
|
|
356
|
-
document.getElementById('connectorApiKey').value = '';
|
|
357
|
-
document.getElementById('connectorApiKey').placeholder = detail.hasKey ? '(key saved — leave blank to keep)' : 'Enter your API key';
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
document.getElementById('connectorModal').style.display = 'flex';
|
|
361
|
-
});
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
var currentOAuthMode = 'manual';
|
|
365
|
-
|
|
366
|
-
function setOAuthMode(mode) {
|
|
367
|
-
currentOAuthMode = mode;
|
|
368
|
-
document.getElementById('connectorManualGroup').style.display = mode === 'manual' ? '' : 'none';
|
|
369
|
-
document.getElementById('connectorAppGroup').style.display = mode === 'app' ? '' : 'none';
|
|
370
|
-
document.getElementById('oauthModeManual').className = 'filter-btn' + (mode === 'manual' ? ' active' : '');
|
|
371
|
-
document.getElementById('oauthModeApp').className = 'filter-btn' + (mode === 'app' ? ' active' : '');
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
document.getElementById('oauthModeManual').addEventListener('click', function() { setOAuthMode('manual'); });
|
|
375
|
-
document.getElementById('oauthModeApp').addEventListener('click', function() { setOAuthMode('app'); });
|
|
376
|
-
|
|
377
|
-
function closeConnectorModal() {
|
|
378
|
-
document.getElementById('connectorModal').style.display = 'none';
|
|
379
|
-
currentConnectorId = null;
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
document.getElementById('connectorCancelBtn').addEventListener('click', closeConnectorModal);
|
|
383
|
-
|
|
384
|
-
document.getElementById('connectorModal').addEventListener('click', function(e) {
|
|
385
|
-
if (e.target === this) closeConnectorModal();
|
|
386
|
-
});
|
|
387
|
-
|
|
388
|
-
document.getElementById('connectorSaveBtn').addEventListener('click', function() {
|
|
389
|
-
if (!currentConnectorId) return;
|
|
390
|
-
var isOAuth = currentConnectorDetail && currentConnectorDetail.authStrategy === 'oauth2';
|
|
391
|
-
var body;
|
|
392
|
-
if (isOAuth) {
|
|
393
|
-
body = { enabled: document.getElementById('connectorEnabled').checked };
|
|
394
|
-
if (currentOAuthMode === 'manual') {
|
|
395
|
-
// Manual token entry
|
|
396
|
-
var token = document.getElementById('oauth-field-accessToken').value;
|
|
397
|
-
if (token) body.accessToken = token;
|
|
398
|
-
var uid = document.getElementById('oauth-field-userId').value;
|
|
399
|
-
if (uid) body.userId = uid;
|
|
400
|
-
} else {
|
|
401
|
-
// OAuth app credentials
|
|
402
|
-
(currentConnectorDetail.fields || []).forEach(function(f) {
|
|
403
|
-
var el = document.getElementById('oauth-field-' + f.name);
|
|
404
|
-
if (el && el.value) body[f.name] = el.value;
|
|
405
|
-
});
|
|
406
|
-
}
|
|
407
|
-
} else {
|
|
408
|
-
body = {
|
|
409
|
-
apiKey: document.getElementById('connectorApiKey').value,
|
|
410
|
-
enabled: document.getElementById('connectorEnabled').checked
|
|
411
|
-
};
|
|
412
|
-
}
|
|
413
|
-
fetch('/api/connectors/' + encodeURIComponent(currentConnectorId), {
|
|
414
|
-
method: 'POST',
|
|
415
|
-
headers: { 'Content-Type': 'application/json' },
|
|
416
|
-
body: JSON.stringify(body)
|
|
417
|
-
}).then(function(r) {
|
|
418
|
-
if (r.ok) { closeConnectorModal(); loadConnectors(); }
|
|
419
|
-
});
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
document.getElementById('connectorConnectBtn').addEventListener('click', function() {
|
|
423
|
-
if (!currentConnectorId || !currentConnectorDetail) return;
|
|
424
|
-
// Save credentials first, then redirect to authorize
|
|
425
|
-
var body = { enabled: true };
|
|
426
|
-
(currentConnectorDetail.fields || []).forEach(function(f) {
|
|
427
|
-
var el = document.getElementById('oauth-field-' + f.name);
|
|
428
|
-
if (el && el.value) body[f.name] = el.value;
|
|
429
|
-
});
|
|
430
|
-
fetch('/api/connectors/' + encodeURIComponent(currentConnectorId), {
|
|
431
|
-
method: 'POST',
|
|
432
|
-
headers: { 'Content-Type': 'application/json' },
|
|
433
|
-
body: JSON.stringify(body)
|
|
434
|
-
}).then(function(r) {
|
|
435
|
-
if (r.ok) {
|
|
436
|
-
window.location.href = '/api/connectors/' + encodeURIComponent(currentConnectorId) + '/authorize';
|
|
437
|
-
}
|
|
438
|
-
});
|
|
439
|
-
});
|
|
440
|
-
|
|
441
|
-
document.getElementById('connectorDisconnectBtn').addEventListener('click', function() {
|
|
442
|
-
if (!currentConnectorId) return;
|
|
443
|
-
fetch('/api/connectors/' + encodeURIComponent(currentConnectorId), { method: 'DELETE' }).then(function(r) {
|
|
444
|
-
if (r.ok) { closeConnectorModal(); loadConnectors(); }
|
|
445
|
-
});
|
|
446
|
-
});
|
|
447
|
-
|
|
448
|
-
document.getElementById('connectorRemoveBtn').addEventListener('click', function() {
|
|
449
|
-
if (!currentConnectorId) return;
|
|
450
|
-
fetch('/api/connectors/' + encodeURIComponent(currentConnectorId), { method: 'DELETE' }).then(function(r) {
|
|
451
|
-
if (r.ok) { closeConnectorModal(); loadConnectors(); }
|
|
452
|
-
});
|
|
453
|
-
});
|
|
454
|
-
|
|
455
|
-
document.getElementById('connectorSearch').addEventListener('input', renderConnectorGrid);
|
|
456
|
-
|
|
457
|
-
// Detect OAuth success/error from URL params
|
|
458
|
-
var connectedParam = params.get('connected');
|
|
459
|
-
var errorParam = params.get('error');
|
|
460
|
-
if (connectedParam) {
|
|
461
|
-
// Open the connectors tab and show success
|
|
462
|
-
openSection('connectors');
|
|
463
|
-
setTimeout(function() { openConnectorModal(connectedParam); }, 500);
|
|
464
|
-
// Clean URL
|
|
465
|
-
var cleanUrl = new URL(window.location);
|
|
466
|
-
cleanUrl.searchParams.delete('connected');
|
|
467
|
-
history.replaceState(null, '', cleanUrl);
|
|
468
|
-
}
|
|
469
|
-
if (errorParam) {
|
|
470
|
-
openSection('connectors');
|
|
471
|
-
alert('OAuth error: ' + errorParam);
|
|
472
|
-
var cleanUrl2 = new URL(window.location);
|
|
473
|
-
cleanUrl2.searchParams.delete('error');
|
|
474
|
-
history.replaceState(null, '', cleanUrl2);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
// --- Save logic ---
|
|
478
|
-
function saveAllSettings() {
|
|
479
|
-
var builderApiKey = document.getElementById('serviceApiKey-builder').value;
|
|
480
|
-
var builderModel = document.getElementById('model-builder').value;
|
|
481
|
-
var builderMaxTokens = document.getElementById('maxTokens-builder').value;
|
|
482
|
-
var builderProvider = document.getElementById('provider-builder').value;
|
|
483
|
-
|
|
484
|
-
if (!builderProvider || !builderApiKey || !builderModel || !builderMaxTokens) {
|
|
485
|
-
alert('Please fill in all required Page Builder fields (Provider, API Key, Model, Max Output Tokens).');
|
|
486
|
-
openSection('models');
|
|
487
|
-
return;
|
|
488
|
-
}
|
|
489
|
-
|
|
490
|
-
var models = [
|
|
491
|
-
{
|
|
492
|
-
use: 'builder',
|
|
493
|
-
provider: builderProvider,
|
|
494
|
-
configuration: {
|
|
495
|
-
apiKey: builderApiKey,
|
|
496
|
-
model: builderModel,
|
|
497
|
-
maxTokens: builderMaxTokens
|
|
498
|
-
},
|
|
499
|
-
imageQuality: 'standard',
|
|
500
|
-
instructions: document.getElementById('instructions-builder').value
|
|
501
|
-
},
|
|
502
|
-
{
|
|
503
|
-
use: 'chat',
|
|
504
|
-
provider: document.getElementById('provider-chat').value,
|
|
505
|
-
configuration: {
|
|
506
|
-
apiKey: document.getElementById('serviceApiKey-chat').value,
|
|
507
|
-
model: document.getElementById('model-chat').value,
|
|
508
|
-
maxTokens: document.getElementById('maxTokens-chat').value
|
|
509
|
-
},
|
|
510
|
-
imageQuality: 'standard',
|
|
511
|
-
instructions: document.getElementById('instructions-chat').value
|
|
512
|
-
}
|
|
513
|
-
];
|
|
514
|
-
|
|
515
|
-
var body = {
|
|
516
|
-
version: 2,
|
|
517
|
-
theme: document.getElementById('theme').value,
|
|
518
|
-
models: models,
|
|
519
|
-
features: []
|
|
520
|
-
};
|
|
521
|
-
|
|
522
|
-
fetch('/api/settings', {
|
|
523
|
-
method: 'POST',
|
|
524
|
-
headers: { 'Content-Type': 'application/json' },
|
|
525
|
-
body: JSON.stringify(body)
|
|
526
|
-
}).then(function(response) {
|
|
527
|
-
if (response.ok || response.redirected) {
|
|
528
|
-
if (wizardActive) {
|
|
529
|
-
window.location.href = '/builder?firstRun=true';
|
|
530
|
-
} else {
|
|
531
|
-
window.location.reload();
|
|
532
|
-
}
|
|
533
|
-
} else {
|
|
534
|
-
alert('Failed to save settings. Please try again.');
|
|
535
|
-
}
|
|
536
|
-
}).catch(function(err) {
|
|
537
|
-
console.error('Error saving settings:', err);
|
|
538
|
-
alert('Failed to save settings. Please try again.');
|
|
539
|
-
});
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
document.querySelectorAll('.apply-btn').forEach(function(btn) {
|
|
543
|
-
btn.addEventListener('click', saveAllSettings);
|
|
544
|
-
});
|
|
545
|
-
|
|
546
|
-
// --- Provider helpers ---
|
|
547
|
-
var providersData = [];
|
|
548
|
-
|
|
549
|
-
function populateProviderDropdowns() {
|
|
550
|
-
var providerOptions = providersData.map(function(p) {
|
|
551
|
-
return '<option value="' + p.name + '">' + p.name + '</option>';
|
|
552
|
-
}).join('');
|
|
553
|
-
document.getElementById('provider-builder').innerHTML = providerOptions;
|
|
554
|
-
document.getElementById('provider-chat').innerHTML = providerOptions;
|
|
555
|
-
}
|
|
556
|
-
|
|
557
|
-
function populateModelDropdown(use, providerName) {
|
|
558
|
-
var provider = providersData.find(function(p) { return p.name === providerName; });
|
|
559
|
-
if (!provider) return;
|
|
560
|
-
var models = use === 'builder' ? provider.builderModels : provider.chatModels;
|
|
561
|
-
var options = models.map(function(m) {
|
|
562
|
-
return '<option value="' + m + '">' + m + '</option>';
|
|
563
|
-
}).join('');
|
|
564
|
-
document.getElementById('model-' + use).innerHTML = options;
|
|
565
|
-
}
|
|
566
|
-
|
|
567
|
-
document.getElementById('provider-builder').addEventListener('change', function() {
|
|
568
|
-
populateModelDropdown('builder', this.value);
|
|
569
|
-
});
|
|
570
|
-
document.getElementById('provider-chat').addEventListener('change', function() {
|
|
571
|
-
populateModelDropdown('chat', this.value);
|
|
572
|
-
});
|
|
573
|
-
|
|
574
|
-
// --- Provider signup instructions ---
|
|
575
|
-
var providerInstructions = {
|
|
576
|
-
'Anthropic': 'Sign up at <a href="https://platform.claude.com" target="_blank">platform.claude.com</a>, then get your key at <a href="https://console.anthropic.com/settings/keys" target="_blank">console.anthropic.com/settings/keys</a>.',
|
|
577
|
-
'OpenAI': 'Sign up at <a href="https://auth.openai.com/create-account" target="_blank">auth.openai.com/create-account</a>, then get your key at <a href="https://platform.openai.com/api-keys" target="_blank">platform.openai.com/api-keys</a>.'
|
|
578
|
-
};
|
|
579
|
-
|
|
580
|
-
// --- "More settings" toggle state (works for all users) ---
|
|
581
|
-
var builderAdvanced = false;
|
|
582
|
-
var chatAdvanced = false;
|
|
583
|
-
|
|
584
|
-
function applyAdvancedToggle() {
|
|
585
|
-
document.getElementById('fg-maxTokens-builder').classList.toggle('wizard-hidden', !builderAdvanced);
|
|
586
|
-
document.getElementById('fg-instructions-builder').classList.toggle('wizard-hidden', !builderAdvanced);
|
|
587
|
-
document.getElementById('fg-maxTokens-chat').classList.toggle('wizard-hidden', !chatAdvanced);
|
|
588
|
-
document.getElementById('fg-instructions-chat').classList.toggle('wizard-hidden', !chatAdvanced);
|
|
589
|
-
}
|
|
590
|
-
|
|
591
|
-
document.getElementById('moreSettingsLink').addEventListener('click', function(e) {
|
|
592
|
-
e.preventDefault();
|
|
593
|
-
builderAdvanced = !builderAdvanced;
|
|
594
|
-
this.innerHTML = builderAdvanced ? '▴ Less settings' : '▾ More settings';
|
|
595
|
-
applyAdvancedToggle();
|
|
596
|
-
});
|
|
597
|
-
|
|
598
|
-
document.getElementById('moreSettingsLinkChat').addEventListener('click', function(e) {
|
|
599
|
-
e.preventDefault();
|
|
600
|
-
chatAdvanced = !chatAdvanced;
|
|
601
|
-
this.innerHTML = chatAdvanced ? '▴ Less settings' : '▾ More settings';
|
|
602
|
-
applyAdvancedToggle();
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
// Hide advanced fields by default on load
|
|
606
|
-
applyAdvancedToggle();
|
|
607
|
-
|
|
608
|
-
// --- Wizard state ---
|
|
609
|
-
var wizardActive = false;
|
|
610
|
-
var builderStep = 0; // 0 = provider only, 1 = + API key, 2 = fully configured
|
|
611
|
-
|
|
612
|
-
function updateWizardVisibility() {
|
|
613
|
-
if (!wizardActive) return;
|
|
614
|
-
var fgApiKey = document.getElementById('fg-apikey-builder');
|
|
615
|
-
var fgModel = document.getElementById('fg-model-builder');
|
|
616
|
-
var moreLinkBuilder = document.getElementById('moreSettingsLink');
|
|
617
|
-
var chatCardEl = document.getElementById('chatCard');
|
|
618
|
-
var moreLinkChat = document.getElementById('moreSettingsLinkChat');
|
|
619
|
-
|
|
620
|
-
// Step 0: only provider visible
|
|
621
|
-
fgApiKey.classList.toggle('wizard-hidden', builderStep < 1);
|
|
622
|
-
|
|
623
|
-
// Model dropdown visible at step 2 (auto-selected)
|
|
624
|
-
fgModel.classList.toggle('wizard-hidden', builderStep < 2);
|
|
625
|
-
|
|
626
|
-
// Builder "More settings" hidden until step 2
|
|
627
|
-
moreLinkBuilder.style.display = builderStep >= 2 ? 'inline-block' : 'none';
|
|
628
|
-
if (builderStep < 2) {
|
|
629
|
-
document.getElementById('fg-maxTokens-builder').classList.add('wizard-hidden');
|
|
630
|
-
document.getElementById('fg-instructions-builder').classList.add('wizard-hidden');
|
|
631
|
-
} else {
|
|
632
|
-
// Let the toggle state drive visibility
|
|
633
|
-
applyAdvancedToggle();
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
// Chat card: before step 2, show only title grayed out
|
|
637
|
-
if (builderStep < 2) {
|
|
638
|
-
['fg-provider-chat', 'fg-apikey-chat', 'fg-model-chat', 'fg-maxTokens-chat', 'fg-instructions-chat'].forEach(function(id) {
|
|
639
|
-
document.getElementById(id).classList.add('wizard-hidden');
|
|
640
|
-
});
|
|
641
|
-
moreLinkChat.style.display = 'none';
|
|
642
|
-
chatCardEl.classList.add('disabled');
|
|
643
|
-
} else {
|
|
644
|
-
// Step 2: show chat card populated — provider, key, model visible; advanced behind toggle
|
|
645
|
-
['fg-provider-chat', 'fg-apikey-chat', 'fg-model-chat'].forEach(function(id) {
|
|
646
|
-
document.getElementById(id).classList.remove('wizard-hidden');
|
|
647
|
-
});
|
|
648
|
-
moreLinkChat.style.display = 'inline-block';
|
|
649
|
-
applyAdvancedToggle();
|
|
650
|
-
chatCardEl.classList.remove('disabled');
|
|
651
|
-
}
|
|
652
|
-
|
|
653
|
-
updateApplyButton();
|
|
654
|
-
}
|
|
655
|
-
|
|
656
|
-
function updateApplyButton() {
|
|
657
|
-
var btns = document.querySelectorAll('.apply-btn');
|
|
658
|
-
if (!wizardActive) {
|
|
659
|
-
btns.forEach(function(b) { b.disabled = false; });
|
|
660
|
-
return;
|
|
661
|
-
}
|
|
662
|
-
var hasProvider = !!document.getElementById('provider-builder').value;
|
|
663
|
-
var hasKey = !!document.getElementById('serviceApiKey-builder').value;
|
|
664
|
-
var hasModel = !!document.getElementById('model-builder').value;
|
|
665
|
-
var hasTokens = !!document.getElementById('maxTokens-builder').value;
|
|
666
|
-
var ready = hasProvider && hasKey && hasModel && hasTokens;
|
|
667
|
-
btns.forEach(function(b) { b.disabled = !ready; });
|
|
668
|
-
}
|
|
669
|
-
|
|
670
|
-
function autoPopulateChatCard() {
|
|
671
|
-
var providerVal = document.getElementById('provider-builder').value;
|
|
672
|
-
var apiKeyVal = document.getElementById('serviceApiKey-builder').value;
|
|
673
|
-
|
|
674
|
-
document.getElementById('provider-chat').value = providerVal;
|
|
675
|
-
populateModelDropdown('chat', providerVal);
|
|
676
|
-
|
|
677
|
-
var chatModelSelect = document.getElementById('model-chat');
|
|
678
|
-
if (chatModelSelect.options.length > 0) {
|
|
679
|
-
chatModelSelect.selectedIndex = 0;
|
|
680
|
-
}
|
|
681
|
-
|
|
682
|
-
document.getElementById('serviceApiKey-chat').value = apiKeyVal;
|
|
683
|
-
document.getElementById('maxTokens-chat').value = '32000';
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// --- Wizard event listeners ---
|
|
687
|
-
document.getElementById('provider-builder').addEventListener('change', function() {
|
|
688
|
-
if (!wizardActive) return;
|
|
689
|
-
var val = this.value;
|
|
690
|
-
if (!val) return;
|
|
691
|
-
if (builderStep < 1) builderStep = 1;
|
|
692
|
-
var instrEl = document.getElementById('providerInstructions');
|
|
693
|
-
if (providerInstructions[val]) {
|
|
694
|
-
instrEl.innerHTML = providerInstructions[val];
|
|
695
|
-
instrEl.style.display = 'block';
|
|
696
|
-
} else {
|
|
697
|
-
instrEl.style.display = 'none';
|
|
698
|
-
}
|
|
699
|
-
updateWizardVisibility();
|
|
700
|
-
});
|
|
701
|
-
|
|
702
|
-
document.getElementById('serviceApiKey-builder').addEventListener('input', function() {
|
|
703
|
-
if (!wizardActive) return;
|
|
704
|
-
if (this.value.length > 0 && builderStep < 2) {
|
|
705
|
-
builderStep = 2;
|
|
706
|
-
document.getElementById('providerInstructions').style.display = 'none';
|
|
707
|
-
document.getElementById('maxTokens-builder').value = '32000';
|
|
708
|
-
autoPopulateChatCard();
|
|
709
|
-
updateWizardVisibility();
|
|
710
|
-
}
|
|
711
|
-
updateApplyButton();
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
// --- Load data ---
|
|
715
|
-
var isConfigured = false;
|
|
716
|
-
|
|
717
|
-
Promise.all([
|
|
718
|
-
fetch('/api/settings').then(function(r) { return r.json(); }),
|
|
719
|
-
fetch('/api/themes').then(function(r) { return r.json(); })
|
|
720
|
-
]).then(function(results) {
|
|
721
|
-
var data = results[0], themes = results[1];
|
|
722
|
-
|
|
723
|
-
// Store providers data
|
|
724
|
-
providersData = data.providers || [];
|
|
725
|
-
|
|
726
|
-
// Find builder and chat entries from models array
|
|
727
|
-
var models = data.models || [];
|
|
728
|
-
var builder = models.find(function(m) { return m.use === 'builder'; }) || {};
|
|
729
|
-
var chat = models.find(function(m) { return m.use === 'chat'; }) || {};
|
|
730
|
-
|
|
731
|
-
var builderConfig = builder.configuration || {};
|
|
732
|
-
var chatConfig = chat.configuration || {};
|
|
733
|
-
var builderApiKey = builderConfig.apiKey || '';
|
|
734
|
-
var builderModel = builderConfig.model || '';
|
|
735
|
-
var builderMaxTokens = builderConfig.maxTokens || '';
|
|
736
|
-
isConfigured = builderApiKey && builderModel && builderMaxTokens;
|
|
737
|
-
|
|
738
|
-
// Populate provider dropdowns
|
|
739
|
-
populateProviderDropdowns();
|
|
740
|
-
|
|
741
|
-
// Builder fields
|
|
742
|
-
document.getElementById('provider-builder').value = builder.provider || 'Anthropic';
|
|
743
|
-
populateModelDropdown('builder', builder.provider || 'Anthropic');
|
|
744
|
-
document.getElementById('serviceApiKey-builder').value = builderApiKey;
|
|
745
|
-
document.getElementById('model-builder').value = builderModel;
|
|
746
|
-
document.getElementById('maxTokens-builder').value = builderMaxTokens;
|
|
747
|
-
document.getElementById('instructions-builder').value = builder.instructions || '';
|
|
748
|
-
|
|
749
|
-
// Chat fields
|
|
750
|
-
document.getElementById('provider-chat').value = chat.provider || 'Anthropic';
|
|
751
|
-
populateModelDropdown('chat', chat.provider || 'Anthropic');
|
|
752
|
-
document.getElementById('serviceApiKey-chat').value = chatConfig.apiKey || '';
|
|
753
|
-
document.getElementById('model-chat').value = chatConfig.model || '';
|
|
754
|
-
document.getElementById('maxTokens-chat').value = chatConfig.maxTokens || '';
|
|
755
|
-
document.getElementById('instructions-chat').value = chat.instructions || '';
|
|
756
|
-
|
|
757
|
-
var currentTheme = data.theme || 'nebula-dusk';
|
|
758
|
-
document.getElementById('theme').innerHTML = themes.map(function(t) {
|
|
759
|
-
return '<option value="' + t + '">' + t + '</option>';
|
|
760
|
-
}).join('');
|
|
761
|
-
document.getElementById('theme').value = currentTheme;
|
|
762
|
-
|
|
763
|
-
loadConnectors();
|
|
764
|
-
|
|
765
|
-
var isFirstRun = params.get('firstRun') === '1';
|
|
766
|
-
|
|
767
|
-
if (!isConfigured) {
|
|
768
|
-
// Disable chat and navigation
|
|
769
|
-
document.getElementById('chatInput').disabled = true;
|
|
770
|
-
document.getElementById('chatInput').classList.add('disabled');
|
|
771
|
-
var pagesLink = document.getElementById('pagesLink');
|
|
772
|
-
pagesLink.style.opacity = '0.4';
|
|
773
|
-
pagesLink.style.pointerEvents = 'none';
|
|
774
|
-
|
|
775
|
-
// Show config required banner and open models section
|
|
776
|
-
document.getElementById('configBanner').style.display = 'block';
|
|
777
|
-
openSection('models');
|
|
778
|
-
}
|
|
779
|
-
|
|
780
|
-
if (isFirstRun) {
|
|
781
|
-
// Activate wizard — always treat as unconfigured when firstRun=1
|
|
782
|
-
wizardActive = true;
|
|
783
|
-
builderStep = 0;
|
|
784
|
-
|
|
785
|
-
// Disable chat and navigation (even if somehow configured)
|
|
786
|
-
document.getElementById('chatInput').disabled = true;
|
|
787
|
-
document.getElementById('chatInput').classList.add('disabled');
|
|
788
|
-
|
|
789
|
-
// Disable Copy, Pages, and Reload links
|
|
790
|
-
['saveLink', 'pagesLink', 'resetLink'].forEach(function(id) {
|
|
791
|
-
var el = document.getElementById(id);
|
|
792
|
-
el.style.opacity = '0.4';
|
|
793
|
-
el.style.pointerEvents = 'none';
|
|
794
|
-
});
|
|
795
|
-
|
|
796
|
-
// Show firstRun greeting, hide default
|
|
797
|
-
document.getElementById('defaultGreeting').style.display = 'none';
|
|
798
|
-
document.getElementById('firstRunGreeting').style.display = '';
|
|
799
|
-
|
|
800
|
-
// Show banner and lock to models tab
|
|
801
|
-
document.getElementById('configBanner').style.display = 'block';
|
|
802
|
-
openSection('models');
|
|
803
|
-
|
|
804
|
-
// Disable other accordion tabs
|
|
805
|
-
document.querySelector('.accordion-section[data-section="general"]').classList.add('disabled');
|
|
806
|
-
document.querySelector('.accordion-section[data-section="connectors"]').classList.add('disabled');
|
|
807
|
-
|
|
808
|
-
// Clear any existing values so wizard starts fresh
|
|
809
|
-
document.getElementById('provider-builder').value = '';
|
|
810
|
-
document.getElementById('serviceApiKey-builder').value = '';
|
|
811
|
-
document.getElementById('model-builder').innerHTML = '<option value="">Select a model</option>';
|
|
812
|
-
document.getElementById('maxTokens-builder').value = '';
|
|
813
|
-
document.getElementById('instructions-builder').value = '';
|
|
814
|
-
document.getElementById('provider-chat').value = '';
|
|
815
|
-
document.getElementById('serviceApiKey-chat').value = '';
|
|
816
|
-
document.getElementById('model-chat').innerHTML = '<option value="">Select a model</option>';
|
|
817
|
-
document.getElementById('maxTokens-chat').value = '';
|
|
818
|
-
document.getElementById('instructions-chat').value = '';
|
|
819
|
-
|
|
820
|
-
// Add placeholder option to builder provider dropdown
|
|
821
|
-
var builderProviderSelect = document.getElementById('provider-builder');
|
|
822
|
-
var placeholder = document.createElement('option');
|
|
823
|
-
placeholder.value = '';
|
|
824
|
-
placeholder.textContent = 'Select a provider';
|
|
825
|
-
placeholder.disabled = true;
|
|
826
|
-
placeholder.selected = true;
|
|
827
|
-
builderProviderSelect.insertBefore(placeholder, builderProviderSelect.firstChild);
|
|
828
|
-
builderProviderSelect.value = '';
|
|
829
|
-
|
|
830
|
-
// Disable Apply buttons until configured
|
|
831
|
-
document.querySelectorAll('.apply-btn').forEach(function(b) { b.disabled = true; });
|
|
832
|
-
|
|
833
|
-
updateWizardVisibility();
|
|
834
|
-
}
|
|
835
|
-
}).catch(function(error) {
|
|
836
|
-
console.error('Error fetching settings:', error);
|
|
837
|
-
});
|
|
838
|
-
</script>
|
|
839
|
-
<script id="page-helpers" src="/api/page-helpers.js?v=2" data-locked="true"></script>
|
|
840
|
-
<script id="page-script" src="/api/page-script.js?v=2" data-locked="true"></script>
|
|
841
|
-
</body></html>
|