@tpitre/story-ui 2.2.0 → 2.3.1

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.
Files changed (188) hide show
  1. package/.env.sample +82 -11
  2. package/README.md +89 -0
  3. package/dist/cli/deploy.d.ts +17 -0
  4. package/dist/cli/deploy.d.ts.map +1 -0
  5. package/dist/cli/deploy.js +696 -0
  6. package/dist/cli/index.d.ts +3 -0
  7. package/dist/cli/index.d.ts.map +1 -0
  8. package/dist/cli/index.js +26 -2
  9. package/dist/cli/setup.d.ts +11 -0
  10. package/dist/cli/setup.d.ts.map +1 -0
  11. package/dist/cli/setup.js +437 -110
  12. package/dist/mcp-server/index.d.ts +2 -0
  13. package/dist/mcp-server/index.d.ts.map +1 -0
  14. package/dist/mcp-server/index.js +120 -2
  15. package/dist/mcp-server/mcp-stdio-server.d.ts +3 -0
  16. package/dist/mcp-server/mcp-stdio-server.d.ts.map +1 -0
  17. package/dist/mcp-server/mcp-stdio-server.js +8 -1
  18. package/dist/mcp-server/routes/claude.d.ts +3 -0
  19. package/dist/mcp-server/routes/claude.d.ts.map +1 -0
  20. package/dist/mcp-server/routes/claude.js +60 -23
  21. package/dist/mcp-server/routes/components.d.ts +4 -0
  22. package/dist/mcp-server/routes/components.d.ts.map +1 -0
  23. package/dist/mcp-server/routes/frameworks.d.ts +38 -0
  24. package/dist/mcp-server/routes/frameworks.d.ts.map +1 -0
  25. package/dist/mcp-server/routes/frameworks.js +183 -0
  26. package/dist/mcp-server/routes/generateStory.d.ts +3 -0
  27. package/dist/mcp-server/routes/generateStory.d.ts.map +1 -0
  28. package/dist/mcp-server/routes/generateStory.js +160 -76
  29. package/dist/mcp-server/routes/generateStoryStream.d.ts +12 -0
  30. package/dist/mcp-server/routes/generateStoryStream.d.ts.map +1 -0
  31. package/dist/mcp-server/routes/generateStoryStream.js +947 -0
  32. package/dist/mcp-server/routes/hybridStories.d.ts +18 -0
  33. package/dist/mcp-server/routes/hybridStories.d.ts.map +1 -0
  34. package/dist/mcp-server/routes/mcpRemote.d.ts +14 -0
  35. package/dist/mcp-server/routes/mcpRemote.d.ts.map +1 -0
  36. package/dist/mcp-server/routes/mcpRemote.js +489 -0
  37. package/dist/mcp-server/routes/memoryStories.d.ts +26 -0
  38. package/dist/mcp-server/routes/memoryStories.d.ts.map +1 -0
  39. package/dist/mcp-server/routes/providers.d.ts +89 -0
  40. package/dist/mcp-server/routes/providers.d.ts.map +1 -0
  41. package/dist/mcp-server/routes/providers.js +369 -0
  42. package/dist/mcp-server/routes/storySync.d.ts +26 -0
  43. package/dist/mcp-server/routes/storySync.d.ts.map +1 -0
  44. package/dist/mcp-server/routes/streamTypes.d.ts +110 -0
  45. package/dist/mcp-server/routes/streamTypes.d.ts.map +1 -0
  46. package/dist/mcp-server/routes/streamTypes.js +18 -0
  47. package/dist/mcp-server/sessionManager.d.ts +50 -0
  48. package/dist/mcp-server/sessionManager.d.ts.map +1 -0
  49. package/dist/story-generator/componentBlacklist.d.ts +21 -0
  50. package/dist/story-generator/componentBlacklist.d.ts.map +1 -0
  51. package/dist/story-generator/componentDiscovery.d.ts +28 -0
  52. package/dist/story-generator/componentDiscovery.d.ts.map +1 -0
  53. package/dist/story-generator/componentRegistryGenerator.d.ts +49 -0
  54. package/dist/story-generator/componentRegistryGenerator.d.ts.map +1 -0
  55. package/dist/story-generator/componentRegistryGenerator.js +205 -0
  56. package/dist/story-generator/configLoader.d.ts +33 -0
  57. package/dist/story-generator/configLoader.d.ts.map +1 -0
  58. package/dist/story-generator/considerationsLoader.d.ts +32 -0
  59. package/dist/story-generator/considerationsLoader.d.ts.map +1 -0
  60. package/dist/story-generator/documentation-sources.d.ts +28 -0
  61. package/dist/story-generator/documentation-sources.d.ts.map +1 -0
  62. package/dist/story-generator/documentationLoader.d.ts +64 -0
  63. package/dist/story-generator/documentationLoader.d.ts.map +1 -0
  64. package/dist/story-generator/dynamicPackageDiscovery.d.ts +97 -0
  65. package/dist/story-generator/dynamicPackageDiscovery.d.ts.map +1 -0
  66. package/dist/story-generator/enhancedComponentDiscovery.d.ts +125 -0
  67. package/dist/story-generator/enhancedComponentDiscovery.d.ts.map +1 -0
  68. package/dist/story-generator/enhancedComponentDiscovery.js +111 -11
  69. package/dist/story-generator/framework-adapters/angular-adapter.d.ts +40 -0
  70. package/dist/story-generator/framework-adapters/angular-adapter.d.ts.map +1 -0
  71. package/dist/story-generator/framework-adapters/angular-adapter.js +427 -0
  72. package/dist/story-generator/framework-adapters/base-adapter.d.ts +75 -0
  73. package/dist/story-generator/framework-adapters/base-adapter.d.ts.map +1 -0
  74. package/dist/story-generator/framework-adapters/base-adapter.js +147 -0
  75. package/dist/story-generator/framework-adapters/framework-detector.d.ts +55 -0
  76. package/dist/story-generator/framework-adapters/framework-detector.d.ts.map +1 -0
  77. package/dist/story-generator/framework-adapters/framework-detector.js +323 -0
  78. package/dist/story-generator/framework-adapters/index.d.ts +97 -0
  79. package/dist/story-generator/framework-adapters/index.d.ts.map +1 -0
  80. package/dist/story-generator/framework-adapters/index.js +198 -0
  81. package/dist/story-generator/framework-adapters/react-adapter.d.ts +40 -0
  82. package/dist/story-generator/framework-adapters/react-adapter.d.ts.map +1 -0
  83. package/dist/story-generator/framework-adapters/react-adapter.js +316 -0
  84. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts +40 -0
  85. package/dist/story-generator/framework-adapters/svelte-adapter.d.ts.map +1 -0
  86. package/dist/story-generator/framework-adapters/svelte-adapter.js +372 -0
  87. package/dist/story-generator/framework-adapters/types.d.ts +182 -0
  88. package/dist/story-generator/framework-adapters/types.d.ts.map +1 -0
  89. package/dist/story-generator/framework-adapters/types.js +8 -0
  90. package/dist/story-generator/framework-adapters/vue-adapter.d.ts +36 -0
  91. package/dist/story-generator/framework-adapters/vue-adapter.d.ts.map +1 -0
  92. package/dist/story-generator/framework-adapters/vue-adapter.js +336 -0
  93. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts +54 -0
  94. package/dist/story-generator/framework-adapters/web-components-adapter.d.ts.map +1 -0
  95. package/dist/story-generator/framework-adapters/web-components-adapter.js +387 -0
  96. package/dist/story-generator/generateStory.d.ts +7 -0
  97. package/dist/story-generator/generateStory.d.ts.map +1 -0
  98. package/dist/story-generator/gitignoreManager.d.ts +50 -0
  99. package/dist/story-generator/gitignoreManager.d.ts.map +1 -0
  100. package/dist/story-generator/imageProcessor.d.ts +80 -0
  101. package/dist/story-generator/imageProcessor.d.ts.map +1 -0
  102. package/dist/story-generator/imageProcessor.js +391 -0
  103. package/dist/story-generator/inMemoryStoryService.d.ts +89 -0
  104. package/dist/story-generator/inMemoryStoryService.d.ts.map +1 -0
  105. package/dist/story-generator/llm-providers/base-provider.d.ts +36 -0
  106. package/dist/story-generator/llm-providers/base-provider.d.ts.map +1 -0
  107. package/dist/story-generator/llm-providers/base-provider.js +135 -0
  108. package/dist/story-generator/llm-providers/claude-provider.d.ts +23 -0
  109. package/dist/story-generator/llm-providers/claude-provider.d.ts.map +1 -0
  110. package/dist/story-generator/llm-providers/claude-provider.js +414 -0
  111. package/dist/story-generator/llm-providers/gemini-provider.d.ts +24 -0
  112. package/dist/story-generator/llm-providers/gemini-provider.d.ts.map +1 -0
  113. package/dist/story-generator/llm-providers/gemini-provider.js +406 -0
  114. package/dist/story-generator/llm-providers/index.d.ts +63 -0
  115. package/dist/story-generator/llm-providers/index.d.ts.map +1 -0
  116. package/dist/story-generator/llm-providers/index.js +169 -0
  117. package/dist/story-generator/llm-providers/openai-provider.d.ts +24 -0
  118. package/dist/story-generator/llm-providers/openai-provider.d.ts.map +1 -0
  119. package/dist/story-generator/llm-providers/openai-provider.js +458 -0
  120. package/dist/story-generator/llm-providers/settings-manager.d.ts +75 -0
  121. package/dist/story-generator/llm-providers/settings-manager.d.ts.map +1 -0
  122. package/dist/story-generator/llm-providers/settings-manager.js +173 -0
  123. package/dist/story-generator/llm-providers/story-llm-service.d.ts +79 -0
  124. package/dist/story-generator/llm-providers/story-llm-service.d.ts.map +1 -0
  125. package/dist/story-generator/llm-providers/story-llm-service.js +240 -0
  126. package/dist/story-generator/llm-providers/types.d.ts +153 -0
  127. package/dist/story-generator/llm-providers/types.d.ts.map +1 -0
  128. package/dist/story-generator/llm-providers/types.js +8 -0
  129. package/dist/story-generator/logger.d.ts +14 -0
  130. package/dist/story-generator/logger.d.ts.map +1 -0
  131. package/dist/story-generator/logger.js +96 -29
  132. package/dist/story-generator/postProcessStory.d.ts +6 -0
  133. package/dist/story-generator/postProcessStory.d.ts.map +1 -0
  134. package/dist/story-generator/productionGitignoreManager.d.ts +91 -0
  135. package/dist/story-generator/productionGitignoreManager.d.ts.map +1 -0
  136. package/dist/story-generator/promptGenerator.d.ts +48 -0
  137. package/dist/story-generator/promptGenerator.d.ts.map +1 -0
  138. package/dist/story-generator/promptGenerator.js +186 -1
  139. package/dist/story-generator/storyHistory.d.ts +44 -0
  140. package/dist/story-generator/storyHistory.d.ts.map +1 -0
  141. package/dist/story-generator/storySync.d.ts +68 -0
  142. package/dist/story-generator/storySync.d.ts.map +1 -0
  143. package/dist/story-generator/storyTracker.d.ts +48 -0
  144. package/dist/story-generator/storyTracker.d.ts.map +1 -0
  145. package/dist/story-generator/storyValidator.d.ts +6 -0
  146. package/dist/story-generator/storyValidator.d.ts.map +1 -0
  147. package/dist/story-generator/universalDesignSystemAdapter.d.ts +68 -0
  148. package/dist/story-generator/universalDesignSystemAdapter.d.ts.map +1 -0
  149. package/dist/story-generator/universalDesignSystemAdapter.js +138 -1
  150. package/dist/story-generator/urlRedirectService.d.ts +21 -0
  151. package/dist/story-generator/urlRedirectService.d.ts.map +1 -0
  152. package/dist/story-generator/validateStory.d.ts +19 -0
  153. package/dist/story-generator/validateStory.d.ts.map +1 -0
  154. package/dist/story-generator/validateStory.js +6 -2
  155. package/dist/story-generator/visionPrompts.d.ts +88 -0
  156. package/dist/story-generator/visionPrompts.d.ts.map +1 -0
  157. package/dist/story-generator/visionPrompts.js +462 -0
  158. package/dist/story-ui.config.d.ts +78 -0
  159. package/dist/story-ui.config.d.ts.map +1 -0
  160. package/dist/templates/StoryUI/StoryUIPanel.d.ts +4 -0
  161. package/dist/templates/StoryUI/StoryUIPanel.d.ts.map +1 -0
  162. package/dist/templates/StoryUI/StoryUIPanel.js +1874 -0
  163. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts +18 -0
  164. package/dist/templates/StoryUI/StoryUIPanel.stories.d.ts.map +1 -0
  165. package/dist/templates/StoryUI/StoryUIPanel.stories.js +37 -0
  166. package/dist/templates/StoryUI/index.d.ts +3 -0
  167. package/dist/templates/StoryUI/index.d.ts.map +1 -0
  168. package/dist/templates/StoryUI/index.js +2 -0
  169. package/package.json +17 -3
  170. package/templates/StoryUI/StoryUIPanel.tsx +1960 -384
  171. package/templates/StoryUI/index.tsx +1 -1
  172. package/templates/StoryUI/manager.tsx +264 -0
  173. package/templates/production-app/.env.example +11 -0
  174. package/templates/production-app/index.html +66 -0
  175. package/templates/production-app/package.json +30 -0
  176. package/templates/production-app/public/favicon.svg +5 -0
  177. package/templates/production-app/src/App.tsx +1560 -0
  178. package/templates/production-app/src/LivePreviewRenderer.tsx +420 -0
  179. package/templates/production-app/src/componentRegistry.ts +315 -0
  180. package/templates/production-app/src/considerations.ts +16 -0
  181. package/templates/production-app/src/index.css +284 -0
  182. package/templates/production-app/src/main.tsx +25 -0
  183. package/templates/production-app/tsconfig.json +32 -0
  184. package/templates/production-app/tsconfig.node.json +11 -0
  185. package/templates/production-app/vite.config.ts +83 -0
  186. package/templates/react-import-rule.json +2 -2
  187. package/dist/index.js +0 -12
  188. package/dist/story-ui.config.loader.js +0 -205
@@ -0,0 +1,173 @@
1
+ /**
2
+ * LLM Settings Manager
3
+ *
4
+ * Manages hybrid configuration for LLM provider/model selection.
5
+ * Combines environment variables (DevOps guardrails) with user preferences.
6
+ *
7
+ * Environment Variables:
8
+ * - DEFAULT_PROVIDER: Default provider (claude, openai, gemini)
9
+ * - DEFAULT_MODEL: Default model ID
10
+ * - ALLOWED_MODELS: Comma-separated list of allowed model IDs (optional)
11
+ * - ALLOWED_PROVIDERS: Comma-separated list of allowed providers (optional)
12
+ * - SINGLE_PROVIDER_MODE: Hide provider selection (true/false)
13
+ */
14
+ import { getProviderRegistry } from './index.js';
15
+ import { logger } from '../logger.js';
16
+ /**
17
+ * Load settings configuration from environment
18
+ */
19
+ export function loadSettingsConfig() {
20
+ const defaultProvider = process.env.DEFAULT_PROVIDER || 'claude';
21
+ const defaultModel = process.env.DEFAULT_MODEL || 'claude-sonnet-4-5-20250929';
22
+ // Parse allowed providers
23
+ const allowedProvidersEnv = process.env.ALLOWED_PROVIDERS;
24
+ const allowedProviders = allowedProvidersEnv
25
+ ? allowedProvidersEnv.split(',').map(p => p.trim())
26
+ : ['claude', 'openai', 'gemini']; // All providers allowed by default
27
+ // Parse allowed models
28
+ const allowedModelsEnv = process.env.ALLOWED_MODELS;
29
+ const allowedModels = allowedModelsEnv
30
+ ? allowedModelsEnv.split(',').map(m => m.trim())
31
+ : []; // Empty means all models allowed
32
+ // Single provider mode
33
+ const singleProviderMode = process.env.SINGLE_PROVIDER_MODE === 'true';
34
+ return {
35
+ defaultProvider,
36
+ defaultModel,
37
+ allowedProviders,
38
+ allowedModels,
39
+ singleProviderMode,
40
+ };
41
+ }
42
+ /**
43
+ * Get available providers for UI selection
44
+ */
45
+ export function getAvailableProviders(config) {
46
+ const registry = getProviderRegistry();
47
+ const configuredProviders = registry.getConfiguredProviders();
48
+ // Filter to only configured and allowed providers
49
+ const available = configuredProviders.filter((provider) => config.allowedProviders.includes(provider.type));
50
+ const providerNames = {
51
+ claude: 'Anthropic Claude',
52
+ openai: 'OpenAI',
53
+ gemini: 'Google Gemini',
54
+ ollama: 'Ollama (Local)',
55
+ custom: 'Custom Provider',
56
+ };
57
+ const recommendedProviders = ['claude', 'openai', 'gemini'];
58
+ return available.map((provider) => ({
59
+ id: provider.type,
60
+ name: providerNames[provider.type] || provider.type,
61
+ isDefault: provider.type === config.defaultProvider,
62
+ isRecommended: recommendedProviders.includes(provider.type),
63
+ }));
64
+ }
65
+ /**
66
+ * Get available models for a provider
67
+ */
68
+ export function getAvailableModels(provider, config) {
69
+ const registry = getProviderRegistry();
70
+ const providerInstance = registry.get(provider);
71
+ if (!providerInstance) {
72
+ return [];
73
+ }
74
+ const allModels = providerInstance.supportedModels;
75
+ // Filter to allowed models if restrictions are set
76
+ const filteredModels = config.allowedModels.length > 0
77
+ ? allModels.filter((model) => config.allowedModels.includes(model.id))
78
+ : allModels;
79
+ // Mark recommended models based on capabilities
80
+ const recommendedModels = [
81
+ // Claude
82
+ 'claude-sonnet-4-5-20250929',
83
+ 'claude-opus-4-5-20251101',
84
+ // OpenAI
85
+ 'gpt-5.1',
86
+ 'gpt-4o',
87
+ // Gemini
88
+ 'gemini-3-pro',
89
+ 'gemini-2.0-flash',
90
+ ];
91
+ return filteredModels.map((model) => ({
92
+ id: model.id,
93
+ name: model.name,
94
+ description: model.description,
95
+ isDefault: model.id === config.defaultModel,
96
+ isRecommended: recommendedModels.includes(model.id),
97
+ }));
98
+ }
99
+ /**
100
+ * Validate user's model selection against configuration
101
+ */
102
+ export function validateSelection(provider, model, config) {
103
+ // Check provider is allowed
104
+ if (!config.allowedProviders.includes(provider)) {
105
+ return {
106
+ valid: false,
107
+ error: `Provider "${provider}" is not allowed. Available: ${config.allowedProviders.join(', ')}`,
108
+ };
109
+ }
110
+ // Check model is allowed (if restrictions set)
111
+ if (config.allowedModels.length > 0 && !config.allowedModels.includes(model)) {
112
+ return {
113
+ valid: false,
114
+ error: `Model "${model}" is not allowed. Please select from available models.`,
115
+ };
116
+ }
117
+ // Check provider is configured
118
+ const registry = getProviderRegistry();
119
+ const providerInstance = registry.get(provider);
120
+ if (!providerInstance || !providerInstance.isConfigured()) {
121
+ return {
122
+ valid: false,
123
+ error: `Provider "${provider}" is not configured. API key may be missing.`,
124
+ };
125
+ }
126
+ return { valid: true };
127
+ }
128
+ /**
129
+ * Get complete settings response for UI
130
+ */
131
+ export function getSettingsForUI(currentProvider, currentModel) {
132
+ const config = loadSettingsConfig();
133
+ // Use current or default
134
+ const provider = currentProvider || config.defaultProvider;
135
+ const model = currentModel || config.defaultModel;
136
+ const providers = config.singleProviderMode
137
+ ? [] // Hide provider selection
138
+ : getAvailableProviders(config);
139
+ const models = getAvailableModels(provider, config);
140
+ return {
141
+ providers,
142
+ models,
143
+ currentProvider: provider,
144
+ currentModel: model,
145
+ config: {
146
+ singleProviderMode: config.singleProviderMode,
147
+ hasRestrictions: config.allowedModels.length > 0,
148
+ },
149
+ };
150
+ }
151
+ /**
152
+ * Apply user settings and return effective provider/model
153
+ */
154
+ export function applyUserSettings(settings) {
155
+ const config = loadSettingsConfig();
156
+ let provider = settings.selectedProvider || config.defaultProvider;
157
+ let model = settings.selectedModel || config.defaultModel;
158
+ let applied = true;
159
+ let fallbackReason;
160
+ // Validate and fallback if needed
161
+ const validation = validateSelection(provider, model, config);
162
+ if (!validation.valid) {
163
+ logger.warn('User settings invalid, using defaults', {
164
+ requested: { provider, model },
165
+ error: validation.error,
166
+ });
167
+ provider = config.defaultProvider;
168
+ model = config.defaultModel;
169
+ applied = false;
170
+ fallbackReason = validation.error;
171
+ }
172
+ return { provider, model, applied, fallbackReason };
173
+ }
@@ -0,0 +1,79 @@
1
+ /**
2
+ * Story LLM Service
3
+ *
4
+ * Service layer that provides LLM functionality specifically for story generation.
5
+ * Wraps the provider system to maintain backwards compatibility while enabling
6
+ * multi-provider support.
7
+ */
8
+ import { LLMProvider, ProviderType, ImageContent, MessageContent } from './index.js';
9
+ /**
10
+ * Get the currently configured provider for story generation
11
+ */
12
+ export declare function getStoryProvider(): LLMProvider;
13
+ /**
14
+ * Check if any provider is configured and ready
15
+ */
16
+ export declare function isProviderConfigured(): boolean;
17
+ /**
18
+ * Get available providers with their configuration status
19
+ */
20
+ export declare function getAvailableProviders(): Array<{
21
+ type: ProviderType;
22
+ name: string;
23
+ configured: boolean;
24
+ models: string[];
25
+ }>;
26
+ /**
27
+ * Simple chat completion for story generation
28
+ * Maintains backwards compatibility with the old callClaude interface
29
+ */
30
+ export declare function chatCompletion(messages: Array<{
31
+ role: 'user' | 'assistant' | 'system';
32
+ content: string;
33
+ }>, options?: {
34
+ model?: string;
35
+ maxTokens?: number;
36
+ temperature?: number;
37
+ }): Promise<string>;
38
+ /**
39
+ * Chat completion with image support for vision-based story generation
40
+ * Supports sending images alongside text prompts
41
+ */
42
+ export declare function chatCompletionWithImages(messages: Array<{
43
+ role: 'user' | 'assistant';
44
+ content: string | MessageContent[];
45
+ }>, options?: {
46
+ model?: string;
47
+ maxTokens?: number;
48
+ temperature?: number;
49
+ }): Promise<string>;
50
+ /**
51
+ * Build a message content array with text and images
52
+ * Helper function for constructing vision requests
53
+ */
54
+ export declare function buildMessageWithImages(text: string, images: ImageContent[]): MessageContent[];
55
+ /**
56
+ * Generate a title for a story using the configured provider
57
+ */
58
+ export declare function generateTitle(description: string): Promise<string>;
59
+ /**
60
+ * Get provider information for UI display
61
+ */
62
+ export declare function getProviderInfo(): {
63
+ currentProvider: string;
64
+ currentModel: string;
65
+ supportsVision: boolean;
66
+ supportsStreaming: boolean;
67
+ };
68
+ /**
69
+ * Configure a specific provider with API key
70
+ */
71
+ export declare function configureProvider(type: ProviderType, apiKey: string, model?: string): boolean;
72
+ /**
73
+ * Validate an API key for a provider
74
+ */
75
+ export declare function validateProviderKey(type: ProviderType, apiKey: string): Promise<{
76
+ valid: boolean;
77
+ error?: string;
78
+ }>;
79
+ //# sourceMappingURL=story-llm-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"story-llm-service.d.ts","sourceRoot":"","sources":["../../../story-generator/llm-providers/story-llm-service.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAKL,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,YAAY,CAAC;AAapB;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,WAAW,CAiB9C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,OAAO,CAG9C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,KAAK,CAAC;IAC7C,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC,CAQD;AAED;;;GAGG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,EAC3E,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,MAAM,CAAC,CAyCjB;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAC5C,QAAQ,EAAE,KAAK,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,OAAO,EAAE,MAAM,GAAG,cAAc,EAAE,CAAC;CACpC,CAAC,EACF,OAAO,CAAC,EAAE;IACR,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,GACA,OAAO,CAAC,MAAM,CAAC,CA2CjB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,YAAY,EAAE,GACrB,cAAc,EAAE,CAelB;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCxE;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI;IACjC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAiBA;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,OAAO,CAiBT;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,YAAY,EAClB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAW7C"}
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Story LLM Service
3
+ *
4
+ * Service layer that provides LLM functionality specifically for story generation.
5
+ * Wraps the provider system to maintain backwards compatibility while enabling
6
+ * multi-provider support.
7
+ */
8
+ import { getProviderRegistry, initializeFromEnv, } from './index.js';
9
+ import { logger } from '../logger.js';
10
+ // Initialize providers from environment on module load
11
+ let initialized = false;
12
+ function ensureInitialized() {
13
+ if (!initialized) {
14
+ initializeFromEnv();
15
+ initialized = true;
16
+ }
17
+ }
18
+ /**
19
+ * Get the currently configured provider for story generation
20
+ */
21
+ export function getStoryProvider() {
22
+ ensureInitialized();
23
+ const registry = getProviderRegistry();
24
+ // First try to get a configured provider
25
+ const configured = registry.getConfiguredProviders();
26
+ if (configured.length > 0) {
27
+ return configured[0];
28
+ }
29
+ // Fall back to default provider (may not be configured)
30
+ const defaultProvider = registry.getDefault();
31
+ if (defaultProvider) {
32
+ return defaultProvider;
33
+ }
34
+ throw new Error('No LLM provider configured. Please set CLAUDE_API_KEY, OPENAI_API_KEY, or GEMINI_API_KEY.');
35
+ }
36
+ /**
37
+ * Check if any provider is configured and ready
38
+ */
39
+ export function isProviderConfigured() {
40
+ ensureInitialized();
41
+ return getProviderRegistry().hasConfiguredProvider();
42
+ }
43
+ /**
44
+ * Get available providers with their configuration status
45
+ */
46
+ export function getAvailableProviders() {
47
+ ensureInitialized();
48
+ return getProviderRegistry().getAll().map(provider => ({
49
+ type: provider.type,
50
+ name: provider.name,
51
+ configured: provider.isConfigured(),
52
+ models: provider.supportedModels.map(m => m.id),
53
+ }));
54
+ }
55
+ /**
56
+ * Simple chat completion for story generation
57
+ * Maintains backwards compatibility with the old callClaude interface
58
+ */
59
+ export async function chatCompletion(messages, options) {
60
+ const provider = getStoryProvider();
61
+ if (!provider.isConfigured()) {
62
+ throw new Error(`${provider.name} provider is not configured. Please set the API key.`);
63
+ }
64
+ // Extract system messages and convert to systemPrompt option
65
+ // This ensures proper handling across all providers
66
+ const systemMessages = messages.filter(msg => msg.role === 'system');
67
+ const nonSystemMessages = messages.filter(msg => msg.role !== 'system');
68
+ const systemPrompt = systemMessages.map(msg => msg.content).join('\n\n') || undefined;
69
+ const chatMessages = nonSystemMessages.map(msg => ({
70
+ role: msg.role,
71
+ content: msg.content,
72
+ }));
73
+ logger.debug('Sending chat request to provider', {
74
+ provider: provider.name,
75
+ model: options?.model || provider.getConfig().model,
76
+ messageCount: chatMessages.length,
77
+ hasSystemPrompt: !!systemPrompt,
78
+ });
79
+ try {
80
+ const response = await provider.chat(chatMessages, {
81
+ model: options?.model,
82
+ maxTokens: options?.maxTokens || 8192,
83
+ temperature: options?.temperature,
84
+ systemPrompt,
85
+ });
86
+ return response.content;
87
+ }
88
+ catch (error) {
89
+ logger.error('LLM chat completion failed', {
90
+ provider: provider.name,
91
+ error: error instanceof Error ? error.message : String(error),
92
+ });
93
+ throw error;
94
+ }
95
+ }
96
+ /**
97
+ * Chat completion with image support for vision-based story generation
98
+ * Supports sending images alongside text prompts
99
+ */
100
+ export async function chatCompletionWithImages(messages, options) {
101
+ const provider = getStoryProvider();
102
+ if (!provider.isConfigured()) {
103
+ throw new Error(`${provider.name} provider is not configured. Please set the API key.`);
104
+ }
105
+ // Check if images are included and provider supports vision
106
+ const hasImages = messages.some(msg => Array.isArray(msg.content) && msg.content.some(c => c.type === 'image'));
107
+ if (hasImages && !provider.supportsVision()) {
108
+ throw new Error(`${provider.name} does not support vision/image analysis. Please use a vision-capable model.`);
109
+ }
110
+ const chatMessages = messages.map(msg => ({
111
+ role: msg.role,
112
+ content: msg.content,
113
+ }));
114
+ logger.debug('Sending chat request with images to provider', {
115
+ provider: provider.name,
116
+ model: options?.model || provider.getConfig().model,
117
+ messageCount: messages.length,
118
+ hasImages,
119
+ });
120
+ try {
121
+ const response = await provider.chat(chatMessages, {
122
+ model: options?.model,
123
+ maxTokens: options?.maxTokens || 8192,
124
+ temperature: options?.temperature,
125
+ });
126
+ return response.content;
127
+ }
128
+ catch (error) {
129
+ logger.error('LLM chat completion with images failed', {
130
+ provider: provider.name,
131
+ error: error instanceof Error ? error.message : String(error),
132
+ });
133
+ throw error;
134
+ }
135
+ }
136
+ /**
137
+ * Build a message content array with text and images
138
+ * Helper function for constructing vision requests
139
+ */
140
+ export function buildMessageWithImages(text, images) {
141
+ const content = [];
142
+ // Add images first so the model sees them before the text instructions
143
+ for (const image of images) {
144
+ content.push(image);
145
+ }
146
+ // Add the text prompt
147
+ content.push({
148
+ type: 'text',
149
+ text,
150
+ });
151
+ return content;
152
+ }
153
+ /**
154
+ * Generate a title for a story using the configured provider
155
+ */
156
+ export async function generateTitle(description) {
157
+ const titlePrompt = [
158
+ 'Given the following UI description, generate a short, clear, human-friendly title suitable for a Storybook navigation item.',
159
+ 'Requirements:',
160
+ '- Do not include words like "Generate", "Build", or "Create"',
161
+ '- Keep it under 50 characters',
162
+ '- Use simple, clear language',
163
+ '- Avoid special characters that could break code (use letters, numbers, spaces, hyphens, and basic punctuation only)',
164
+ '',
165
+ 'UI description:',
166
+ description,
167
+ '',
168
+ 'Title:',
169
+ ].join('\n');
170
+ const response = await chatCompletion([{ role: 'user', content: titlePrompt }], {
171
+ maxTokens: 100,
172
+ temperature: 0.7,
173
+ });
174
+ // Extract the first non-empty line
175
+ const lines = response.split('\n').map(l => l.trim()).filter(Boolean);
176
+ if (lines.length > 0) {
177
+ let title = lines[0].replace(/^['\"]|['\"]$/g, '').trim();
178
+ // Sanitize
179
+ title = title
180
+ .replace(/[^\w\s'"?!-]/g, ' ')
181
+ .replace(/\s+/g, ' ')
182
+ .trim()
183
+ .slice(0, 50);
184
+ return title;
185
+ }
186
+ return '';
187
+ }
188
+ /**
189
+ * Get provider information for UI display
190
+ */
191
+ export function getProviderInfo() {
192
+ try {
193
+ const provider = getStoryProvider();
194
+ return {
195
+ currentProvider: provider.name,
196
+ currentModel: provider.getConfig().model,
197
+ supportsVision: provider.supportsVision(),
198
+ supportsStreaming: provider.supportsStreaming(),
199
+ };
200
+ }
201
+ catch {
202
+ return {
203
+ currentProvider: 'None',
204
+ currentModel: 'None',
205
+ supportsVision: false,
206
+ supportsStreaming: false,
207
+ };
208
+ }
209
+ }
210
+ /**
211
+ * Configure a specific provider with API key
212
+ */
213
+ export function configureProvider(type, apiKey, model) {
214
+ ensureInitialized();
215
+ const registry = getProviderRegistry();
216
+ const provider = registry.get(type);
217
+ if (!provider) {
218
+ logger.error(`Unknown provider type: ${type}`);
219
+ return false;
220
+ }
221
+ registry.configureProvider(type, {
222
+ apiKey,
223
+ model: model || provider.supportedModels[0]?.id,
224
+ });
225
+ logger.info(`Configured ${type} provider`, { model: model || 'default' });
226
+ return true;
227
+ }
228
+ /**
229
+ * Validate an API key for a provider
230
+ */
231
+ export async function validateProviderKey(type, apiKey) {
232
+ ensureInitialized();
233
+ const registry = getProviderRegistry();
234
+ const provider = registry.get(type);
235
+ if (!provider) {
236
+ return { valid: false, error: `Unknown provider type: ${type}` };
237
+ }
238
+ const result = await provider.validateApiKey(apiKey);
239
+ return { valid: result.valid, error: result.error };
240
+ }
@@ -0,0 +1,153 @@
1
+ /**
2
+ * LLM Provider Types and Interfaces
3
+ *
4
+ * This module defines the abstraction layer for multiple LLM providers.
5
+ * Providers like Claude, OpenAI, Gemini, and local models (Ollama) can
6
+ * implement this interface to provide a unified API.
7
+ */
8
+ export interface ChatMessage {
9
+ role: 'user' | 'assistant' | 'system';
10
+ content: string | MessageContent[];
11
+ }
12
+ export interface TextContent {
13
+ type: 'text';
14
+ text: string;
15
+ }
16
+ export interface ImageContent {
17
+ type: 'image';
18
+ source: {
19
+ type: 'base64' | 'url';
20
+ mediaType?: string;
21
+ data?: string;
22
+ url?: string;
23
+ };
24
+ }
25
+ export interface DocumentContent {
26
+ type: 'document';
27
+ source: {
28
+ type: 'base64' | 'url';
29
+ mediaType: string;
30
+ data?: string;
31
+ url?: string;
32
+ name?: string;
33
+ };
34
+ }
35
+ export type MessageContent = TextContent | ImageContent | DocumentContent;
36
+ export interface ModelInfo {
37
+ id: string;
38
+ name: string;
39
+ provider: ProviderType;
40
+ contextWindow: number;
41
+ maxOutputTokens: number;
42
+ supportsVision: boolean;
43
+ supportsDocuments: boolean;
44
+ supportsFunctionCalling: boolean;
45
+ supportsStreaming: boolean;
46
+ supportsReasoning?: boolean;
47
+ inputPricePer1kTokens?: number;
48
+ outputPricePer1kTokens?: number;
49
+ description?: string;
50
+ }
51
+ export type ProviderType = 'claude' | 'openai' | 'gemini' | 'ollama' | 'custom';
52
+ export interface ProviderConfig {
53
+ provider: ProviderType;
54
+ apiKey?: string;
55
+ model: string;
56
+ baseUrl?: string;
57
+ organizationId?: string;
58
+ projectId?: string;
59
+ timeout?: number;
60
+ }
61
+ export interface ChatOptions {
62
+ model?: string;
63
+ maxTokens?: number;
64
+ temperature?: number;
65
+ topP?: number;
66
+ topK?: number;
67
+ stopSequences?: string[];
68
+ systemPrompt?: string;
69
+ stream?: boolean;
70
+ tools?: ToolDefinition[];
71
+ }
72
+ export interface ToolDefinition {
73
+ name: string;
74
+ description: string;
75
+ inputSchema: Record<string, any>;
76
+ }
77
+ export interface ToolCall {
78
+ id: string;
79
+ name: string;
80
+ arguments: Record<string, any>;
81
+ }
82
+ export interface ChatResponse {
83
+ id: string;
84
+ model: string;
85
+ content: string;
86
+ finishReason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | 'error';
87
+ usage: {
88
+ promptTokens: number;
89
+ completionTokens: number;
90
+ totalTokens: number;
91
+ };
92
+ toolCalls?: ToolCall[];
93
+ raw?: any;
94
+ }
95
+ export interface StreamChunk {
96
+ type: 'text' | 'tool_call' | 'error' | 'done';
97
+ content?: string;
98
+ toolCall?: Partial<ToolCall>;
99
+ error?: string;
100
+ usage?: ChatResponse['usage'];
101
+ }
102
+ export interface ImageAnalysis {
103
+ description: string;
104
+ components?: string[];
105
+ layout?: string;
106
+ colors?: string[];
107
+ suggestions?: string[];
108
+ }
109
+ export interface ValidationResult {
110
+ valid: boolean;
111
+ error?: string;
112
+ models?: ModelInfo[];
113
+ }
114
+ /**
115
+ * LLM Provider Interface
116
+ *
117
+ * All LLM providers must implement this interface.
118
+ */
119
+ export interface LLMProvider {
120
+ readonly name: string;
121
+ readonly type: ProviderType;
122
+ readonly supportedModels: ModelInfo[];
123
+ supportsVision(): boolean;
124
+ supportsDocuments(): boolean;
125
+ supportsFunctionCalling(): boolean;
126
+ supportsStreaming(): boolean;
127
+ configure(config: ProviderConfig): void;
128
+ getConfig(): ProviderConfig;
129
+ validateApiKey(apiKey: string): Promise<ValidationResult>;
130
+ isConfigured(): boolean;
131
+ chat(messages: ChatMessage[], options?: ChatOptions): Promise<ChatResponse>;
132
+ chatStream?(messages: ChatMessage[], options?: ChatOptions): AsyncIterable<StreamChunk>;
133
+ analyzeImage?(image: ImageContent, prompt?: string): Promise<ImageAnalysis>;
134
+ estimateTokens?(text: string): number;
135
+ }
136
+ /**
137
+ * Provider Registry
138
+ *
139
+ * Manages available providers and their configurations.
140
+ */
141
+ export interface ProviderRegistry {
142
+ register(provider: LLMProvider): void;
143
+ get(type: ProviderType): LLMProvider | undefined;
144
+ getAll(): LLMProvider[];
145
+ getAvailableModels(): ModelInfo[];
146
+ getDefault(): LLMProvider | undefined;
147
+ setDefault(type: ProviderType): void;
148
+ }
149
+ /**
150
+ * Provider Factory Function Type
151
+ */
152
+ export type ProviderFactory = (config?: Partial<ProviderConfig>) => LLMProvider;
153
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../story-generator/llm-providers/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * LLM Provider Types and Interfaces
3
+ *
4
+ * This module defines the abstraction layer for multiple LLM providers.
5
+ * Providers like Claude, OpenAI, Gemini, and local models (Ollama) can
6
+ * implement this interface to provide a unified API.
7
+ */
8
+ export {};
@@ -0,0 +1,14 @@
1
+ export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';
2
+ declare class Logger {
3
+ private static instance;
4
+ static getInstance(): Logger;
5
+ debug(...args: any[]): void;
6
+ log(...args: any[]): void;
7
+ info(...args: any[]): void;
8
+ warn(...args: any[]): void;
9
+ error(...args: any[]): void;
10
+ structured(level: LogLevel, message: string, data?: Record<string, any>): void;
11
+ }
12
+ export declare const logger: Logger;
13
+ export default logger;
14
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../story-generator/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;AAwDpE,cAAM,MAAM;IACV,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAS;IAEhC,MAAM,CAAC,WAAW,IAAI,MAAM;IAO5B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAU3B,GAAG,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAKzB,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAU1B,IAAI,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAU1B,KAAK,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI;IAO3B,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,IAAI;CAgB/E;AAGD,eAAO,MAAM,MAAM,QAAuB,CAAC;AAG3C,eAAe,MAAM,CAAC"}