@lssm/module.ai-chat 0.0.0-canary-20251217083314 → 0.0.0-canary-20251219202229

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 (100) hide show
  1. package/LICENSE +21 -0
  2. package/dist/ai-chat.feature.d.ts +2 -1
  3. package/dist/ai-chat.feature.d.ts.map +1 -0
  4. package/dist/ai-chat.feature.js +2 -1
  5. package/dist/ai-chat.feature.js.map +1 -0
  6. package/dist/context/context-builder.d.ts +2 -1
  7. package/dist/context/context-builder.d.ts.map +1 -0
  8. package/dist/context/context-builder.js +2 -1
  9. package/dist/context/context-builder.js.map +1 -0
  10. package/dist/context/file-operations.d.ts +2 -1
  11. package/dist/context/file-operations.d.ts.map +1 -0
  12. package/dist/context/file-operations.js +2 -1
  13. package/dist/context/file-operations.js.map +1 -0
  14. package/dist/context/workspace-context.d.ts +2 -1
  15. package/dist/context/workspace-context.d.ts.map +1 -0
  16. package/dist/context/workspace-context.js +2 -1
  17. package/dist/context/workspace-context.js.map +1 -0
  18. package/dist/core/chat-service.d.ts +2 -1
  19. package/dist/core/chat-service.d.ts.map +1 -0
  20. package/dist/core/chat-service.js +2 -1
  21. package/dist/core/chat-service.js.map +1 -0
  22. package/dist/core/conversation-store.d.ts +2 -1
  23. package/dist/core/conversation-store.d.ts.map +1 -0
  24. package/dist/core/conversation-store.js +2 -1
  25. package/dist/core/conversation-store.js.map +1 -0
  26. package/dist/core/message-types.d.ts +2 -1
  27. package/dist/core/message-types.d.ts.map +1 -0
  28. package/dist/libs/ai-providers/dist/factory.js +23 -22
  29. package/dist/libs/ai-providers/dist/factory.js.map +1 -0
  30. package/dist/libs/ai-providers/dist/models.js +2 -1
  31. package/dist/libs/ai-providers/dist/models.js.map +1 -0
  32. package/dist/libs/ai-providers/dist/validation.js +2 -1
  33. package/dist/libs/ai-providers/dist/validation.js.map +1 -0
  34. package/dist/libs/design-system/dist/_virtual/rolldown_runtime.js +2 -1
  35. package/dist/libs/design-system/dist/_virtual/rolldown_runtime.js.map +1 -0
  36. package/dist/libs/design-system/dist/components/atoms/Button.js +5 -4
  37. package/dist/libs/design-system/dist/components/atoms/Button.js.map +1 -0
  38. package/dist/libs/design-system/dist/components/atoms/Textarea.js +5 -4
  39. package/dist/libs/design-system/dist/components/atoms/Textarea.js.map +1 -0
  40. package/dist/libs/design-system/dist/lib/keyboard.js +2 -1
  41. package/dist/libs/design-system/dist/lib/keyboard.js.map +1 -0
  42. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/button.js +2 -1
  43. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/button.js.map +1 -0
  44. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/textarea.js +2 -1
  45. package/dist/libs/design-system/dist/ui-kit-web/dist/ui/textarea.js.map +1 -0
  46. package/dist/libs/design-system/dist/ui-kit-web/dist/ui-kit-core/dist/utils.js +2 -1
  47. package/dist/libs/design-system/dist/ui-kit-web/dist/ui-kit-core/dist/utils.js.map +1 -0
  48. package/dist/libs/ui-kit-web/dist/ui/avatar.js +2 -1
  49. package/dist/libs/ui-kit-web/dist/ui/avatar.js.map +1 -0
  50. package/dist/libs/ui-kit-web/dist/ui/badge.js +2 -1
  51. package/dist/libs/ui-kit-web/dist/ui/badge.js.map +1 -0
  52. package/dist/libs/ui-kit-web/dist/ui/scroll-area.js +2 -1
  53. package/dist/libs/ui-kit-web/dist/ui/scroll-area.js.map +1 -0
  54. package/dist/libs/ui-kit-web/dist/ui/select.js +2 -1
  55. package/dist/libs/ui-kit-web/dist/ui/select.js.map +1 -0
  56. package/dist/libs/ui-kit-web/dist/ui/skeleton.js +2 -1
  57. package/dist/libs/ui-kit-web/dist/ui/skeleton.js.map +1 -0
  58. package/dist/libs/ui-kit-web/dist/ui/tooltip.js +2 -1
  59. package/dist/libs/ui-kit-web/dist/ui/tooltip.js.map +1 -0
  60. package/dist/libs/ui-kit-web/dist/ui/utils.js +2 -1
  61. package/dist/libs/ui-kit-web/dist/ui/utils.js.map +1 -0
  62. package/dist/libs/ui-kit-web/dist/ui-kit-core/dist/utils.js +2 -1
  63. package/dist/libs/ui-kit-web/dist/ui-kit-core/dist/utils.js.map +1 -0
  64. package/dist/presentation/components/ChatContainer.d.ts +2 -1
  65. package/dist/presentation/components/ChatContainer.d.ts.map +1 -0
  66. package/dist/presentation/components/ChatContainer.js +2 -1
  67. package/dist/presentation/components/ChatContainer.js.map +1 -0
  68. package/dist/presentation/components/ChatInput.d.ts +4 -3
  69. package/dist/presentation/components/ChatInput.d.ts.map +1 -0
  70. package/dist/presentation/components/ChatInput.js +8 -7
  71. package/dist/presentation/components/ChatInput.js.map +1 -0
  72. package/dist/presentation/components/ChatMessage.d.ts +7 -6
  73. package/dist/presentation/components/ChatMessage.d.ts.map +1 -0
  74. package/dist/presentation/components/ChatMessage.js +4 -3
  75. package/dist/presentation/components/ChatMessage.js.map +1 -0
  76. package/dist/presentation/components/CodePreview.d.ts +4 -3
  77. package/dist/presentation/components/CodePreview.d.ts.map +1 -0
  78. package/dist/presentation/components/CodePreview.js +8 -7
  79. package/dist/presentation/components/CodePreview.js.map +1 -0
  80. package/dist/presentation/components/ContextIndicator.d.ts +2 -1
  81. package/dist/presentation/components/ContextIndicator.d.ts.map +1 -0
  82. package/dist/presentation/components/ContextIndicator.js +2 -1
  83. package/dist/presentation/components/ContextIndicator.js.map +1 -0
  84. package/dist/presentation/components/ModelPicker.d.ts +6 -5
  85. package/dist/presentation/components/ModelPicker.d.ts.map +1 -0
  86. package/dist/presentation/components/ModelPicker.js +4 -3
  87. package/dist/presentation/components/ModelPicker.js.map +1 -0
  88. package/dist/presentation/hooks/useChat.d.ts +2 -1
  89. package/dist/presentation/hooks/useChat.d.ts.map +1 -0
  90. package/dist/presentation/hooks/useChat.js +2 -1
  91. package/dist/presentation/hooks/useChat.js.map +1 -0
  92. package/dist/presentation/hooks/useProviders.d.ts +2 -1
  93. package/dist/presentation/hooks/useProviders.d.ts.map +1 -0
  94. package/dist/presentation/hooks/useProviders.js +2 -1
  95. package/dist/presentation/hooks/useProviders.js.map +1 -0
  96. package/dist/providers/chat-utilities.d.ts +2 -1
  97. package/dist/providers/chat-utilities.d.ts.map +1 -0
  98. package/dist/providers/chat-utilities.js +2 -1
  99. package/dist/providers/chat-utilities.js.map +1 -0
  100. package/package.json +13 -12
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chaman Ventures, SASU
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -8,4 +8,5 @@ import { FeatureModuleSpec } from "@lssm/lib.contracts";
8
8
  */
9
9
  declare const AiChatFeature: FeatureModuleSpec;
10
10
  //#endregion
11
- export { AiChatFeature };
11
+ export { AiChatFeature };
12
+ //# sourceMappingURL=ai-chat.feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-chat.feature.d.ts","names":[],"sources":["../src/ai-chat.feature.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAWa,eAAe"}
@@ -90,4 +90,5 @@ const AiChatFeature = {
90
90
  };
91
91
 
92
92
  //#endregion
93
- export { AiChatFeature };
93
+ export { AiChatFeature };
94
+ //# sourceMappingURL=ai-chat.feature.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-chat.feature.js","names":["AiChatFeature: FeatureModuleSpec"],"sources":["../src/ai-chat.feature.ts"],"sourcesContent":["/**\n * AI Chat Feature Module Specification\n *\n * Defines the feature module for AI-powered vibe coding chat.\n */\nimport type { FeatureModuleSpec } from '@lssm/lib.contracts';\n\n/**\n * AI Chat feature module that bundles conversational AI assistance\n * for ContractSpec development across CLI, VSCode, and Studio.\n */\nexport const AiChatFeature: FeatureModuleSpec = {\n meta: {\n key: 'ai-chat',\n title: 'AI Vibe Coding Chat',\n description:\n 'AI-powered conversational coding assistant with full workspace context',\n domain: 'platform',\n owners: ['@platform.ai'],\n tags: ['ai', 'chat', 'llm', 'vibe-coding', 'assistant'],\n stability: 'experimental',\n },\n\n // Contract operations for chat functionality\n operations: [\n { name: 'ai-chat.send', version: 1 },\n { name: 'ai-chat.stream', version: 1 },\n { name: 'ai-chat.conversations.list', version: 1 },\n { name: 'ai-chat.conversations.get', version: 1 },\n { name: 'ai-chat.conversations.delete', version: 1 },\n { name: 'ai-chat.providers.list', version: 1 },\n { name: 'ai-chat.context.scan', version: 1 },\n ],\n\n // Events emitted by the chat system\n events: [\n { name: 'ai-chat.message.sent', version: 1 },\n { name: 'ai-chat.message.received', version: 1 },\n { name: 'ai-chat.conversation.created', version: 1 },\n { name: 'ai-chat.conversation.deleted', version: 1 },\n { name: 'ai-chat.error', version: 1 },\n ],\n\n // No presentations for core module\n presentations: [],\n opToPresentation: [],\n presentationsTargets: [],\n\n // Capability definitions\n capabilities: {\n provides: [{ key: 'ai-chat', version: 1 }],\n requires: [\n { key: 'identity', version: 1 },\n { key: 'metering', version: 1 },\n ],\n },\n};\n"],"mappings":";;;;;AAWA,MAAaA,gBAAmC;CAC9C,MAAM;EACJ,KAAK;EACL,OAAO;EACP,aACE;EACF,QAAQ;EACR,QAAQ,CAAC,eAAe;EACxB,MAAM;GAAC;GAAM;GAAQ;GAAO;GAAe;GAAY;EACvD,WAAW;EACZ;CAGD,YAAY;EACV;GAAE,MAAM;GAAgB,SAAS;GAAG;EACpC;GAAE,MAAM;GAAkB,SAAS;GAAG;EACtC;GAAE,MAAM;GAA8B,SAAS;GAAG;EAClD;GAAE,MAAM;GAA6B,SAAS;GAAG;EACjD;GAAE,MAAM;GAAgC,SAAS;GAAG;EACpD;GAAE,MAAM;GAA0B,SAAS;GAAG;EAC9C;GAAE,MAAM;GAAwB,SAAS;GAAG;EAC7C;CAGD,QAAQ;EACN;GAAE,MAAM;GAAwB,SAAS;GAAG;EAC5C;GAAE,MAAM;GAA4B,SAAS;GAAG;EAChD;GAAE,MAAM;GAAgC,SAAS;GAAG;EACpD;GAAE,MAAM;GAAgC,SAAS;GAAG;EACpD;GAAE,MAAM;GAAiB,SAAS;GAAG;EACtC;CAGD,eAAe,EAAE;CACjB,kBAAkB,EAAE;CACpB,sBAAsB,EAAE;CAGxB,cAAc;EACZ,UAAU,CAAC;GAAE,KAAK;GAAW,SAAS;GAAG,CAAC;EAC1C,UAAU,CACR;GAAE,KAAK;GAAY,SAAS;GAAG,EAC/B;GAAE,KAAK;GAAY,SAAS;GAAG,CAChC;EACF;CACF"}
@@ -53,4 +53,5 @@ declare class ContextBuilder {
53
53
  */
54
54
  declare function createContextBuilder(context: WorkspaceContext): ContextBuilder;
55
55
  //#endregion
56
- export { BuiltContext, ContextBuilder, ContextBuilderOptions, ContextEntry, createContextBuilder };
56
+ export { BuiltContext, ContextBuilder, ContextBuilderOptions, ContextEntry, createContextBuilder };
57
+ //# sourceMappingURL=context-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-builder.d.ts","names":[],"sources":["../../src/context/context-builder.ts"],"sourcesContent":[],"mappings":";;;;AA0GA;;;AAU8C,UA1G7B,YAAA,CA0G6B;EAAY,IAAA,EAAA,MAAA,GAAA,MAAA,GAAA,WAAA;EAwI1C,IAAA,EAAA,MAAA;;;;;;;;UAvOC,YAAA;WACN;;;;;;;UAQM,qBAAA;;;;;;;;;;;;;cA4EJ,cAAA;;uBAGU;;;;kBAON,wBAA6B;;;;;;;;;iBAwI9B,oBAAA,UACL,mBACR"}
@@ -144,4 +144,5 @@ function createContextBuilder(context) {
144
144
  }
145
145
 
146
146
  //#endregion
147
- export { ContextBuilder, createContextBuilder };
147
+ export { ContextBuilder, createContextBuilder };
148
+ //# sourceMappingURL=context-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-builder.js","names":["entries: ContextEntry[]","entry: ContextEntry","parts: string[]"],"sources":["../../src/context/context-builder.ts"],"sourcesContent":["/**\n * Context builder for LLM prompts\n *\n * Builds rich context from workspace information for AI assistance.\n */\nimport type { WorkspaceContext, SpecInfo, FileInfo } from './workspace-context';\n\n/**\n * Context entry for a file or spec\n */\nexport interface ContextEntry {\n type: 'spec' | 'file' | 'reference';\n path: string;\n content?: string;\n summary?: string;\n relevance: number; // 0-1 score\n}\n\n/**\n * Built context for LLM\n */\nexport interface BuiltContext {\n entries: ContextEntry[];\n summary: string;\n totalTokensEstimate: number;\n}\n\n/**\n * Options for building context\n */\nexport interface ContextBuilderOptions {\n /** Maximum estimated tokens for context */\n maxTokens?: number;\n /** Query to use for relevance scoring */\n query?: string;\n /** Specific files to include */\n includeFiles?: string[];\n /** Specific specs to include */\n includeSpecs?: string[];\n}\n\n/**\n * Estimates token count from string (rough approximation)\n */\nfunction estimateTokens(text: string): number {\n // Rough estimate: ~4 characters per token\n return Math.ceil(text.length / 4);\n}\n\n/**\n * Calculate relevance score for a spec\n */\nfunction scoreSpec(spec: SpecInfo, query?: string): number {\n if (!query) return 0.5;\n\n const lowerQuery = query.toLowerCase();\n let score = 0;\n\n // Name match\n if (spec.name.toLowerCase().includes(lowerQuery)) {\n score += 0.4;\n }\n\n // Description match\n if (spec.description?.toLowerCase().includes(lowerQuery)) {\n score += 0.3;\n }\n\n // Tag match\n if (spec.tags?.some((t) => t.toLowerCase().includes(lowerQuery))) {\n score += 0.2;\n }\n\n return Math.min(score, 1);\n}\n\n/**\n * Calculate relevance score for a file\n */\nfunction scoreFile(file: FileInfo, query?: string): number {\n if (!query) return 0.5;\n\n const lowerQuery = query.toLowerCase();\n let score = 0;\n\n // Path match\n if (file.path.toLowerCase().includes(lowerQuery)) {\n score += 0.5;\n }\n\n // Name match\n if (file.name.toLowerCase().includes(lowerQuery)) {\n score += 0.3;\n }\n\n // Spec file bonus\n if (file.isSpec) {\n score += 0.2;\n }\n\n return Math.min(score, 1);\n}\n\n/**\n * Context builder for creating rich LLM context\n */\nexport class ContextBuilder {\n private readonly context: WorkspaceContext;\n\n constructor(context: WorkspaceContext) {\n this.context = context;\n }\n\n /**\n * Build context for a chat message\n */\n build(options: ContextBuilderOptions = {}): BuiltContext {\n const maxTokens = options.maxTokens ?? 4000;\n const entries: ContextEntry[] = [];\n let totalTokens = 0;\n\n // Add explicitly included specs\n if (options.includeSpecs?.length) {\n for (const specName of options.includeSpecs) {\n const spec = this.context.getSpecs().find((s) => s.name === specName);\n if (spec) {\n const entry: ContextEntry = {\n type: 'spec',\n path: spec.path,\n summary: `${spec.type}: ${spec.name}${spec.description ? ` - ${spec.description}` : ''}`,\n relevance: 1,\n };\n entries.push(entry);\n totalTokens += estimateTokens(entry.summary ?? '');\n }\n }\n }\n\n // Add explicitly included files\n if (options.includeFiles?.length) {\n for (const filePath of options.includeFiles) {\n const file = this.context.getFiles().find((f) => f.path === filePath);\n if (file) {\n const entry: ContextEntry = {\n type: 'file',\n path: file.path,\n summary: `File: ${file.relativePath}`,\n relevance: 1,\n };\n entries.push(entry);\n totalTokens += estimateTokens(entry.summary ?? '');\n }\n }\n }\n\n // Add relevant specs based on query\n if (options.query) {\n const scoredSpecs = this.context\n .getSpecs()\n .map((spec) => ({ spec, score: scoreSpec(spec, options.query) }))\n .filter(({ score }) => score > 0.2)\n .sort((a, b) => b.score - a.score);\n\n for (const { spec, score } of scoredSpecs) {\n if (totalTokens >= maxTokens) break;\n if (entries.some((e) => e.path === spec.path)) continue;\n\n const entry: ContextEntry = {\n type: 'spec',\n path: spec.path,\n summary: `${spec.type}: ${spec.name}${spec.description ? ` - ${spec.description}` : ''}`,\n relevance: score,\n };\n entries.push(entry);\n totalTokens += estimateTokens(entry.summary ?? '');\n }\n }\n\n // Add relevant files based on query\n if (options.query) {\n const scoredFiles = this.context\n .getFiles()\n .map((file) => ({ file, score: scoreFile(file, options.query) }))\n .filter(({ score }) => score > 0.2)\n .sort((a, b) => b.score - a.score);\n\n for (const { file, score } of scoredFiles) {\n if (totalTokens >= maxTokens) break;\n if (entries.some((e) => e.path === file.path)) continue;\n\n const entry: ContextEntry = {\n type: 'file',\n path: file.path,\n summary: `File: ${file.relativePath}`,\n relevance: score,\n };\n entries.push(entry);\n totalTokens += estimateTokens(entry.summary ?? '');\n }\n }\n\n // Build summary\n const summary = this.buildSummary(entries);\n\n return {\n entries,\n summary,\n totalTokensEstimate: totalTokens + estimateTokens(summary),\n };\n }\n\n /**\n * Build a text summary of the context entries\n */\n private buildSummary(entries: ContextEntry[]): string {\n if (entries.length === 0) {\n return this.context.getContextSummary();\n }\n\n const parts: string[] = [];\n\n // Workspace info\n const workspaceSummary = this.context.getSummary();\n parts.push(`Workspace: ${workspaceSummary.name}`);\n parts.push('');\n\n // Relevant specs\n const specs = entries.filter((e) => e.type === 'spec');\n if (specs.length > 0) {\n parts.push('### Relevant Specs');\n for (const entry of specs) {\n parts.push(`- ${entry.summary}`);\n }\n parts.push('');\n }\n\n // Relevant files\n const files = entries.filter((e) => e.type === 'file');\n if (files.length > 0) {\n parts.push('### Relevant Files');\n for (const entry of files) {\n parts.push(`- ${entry.summary}`);\n }\n }\n\n return parts.join('\\n');\n }\n}\n\n/**\n * Create a context builder\n */\nexport function createContextBuilder(\n context: WorkspaceContext\n): ContextBuilder {\n return new ContextBuilder(context);\n}\n"],"mappings":"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"}
@@ -96,4 +96,5 @@ declare class FileOperations {
96
96
  */
97
97
  declare function createNodeFileOperations(workspacePath: string, allowWrites?: boolean): FileOperations;
98
98
  //#endregion
99
- export { FileOperation, FileOperationResult, FileOperations, FileReadResult, FileSystem, FileWriteResult, createNodeFileOperations };
99
+ export { FileOperation, FileOperationResult, FileOperations, FileReadResult, FileSystem, FileWriteResult, createNodeFileOperations };
100
+ //# sourceMappingURL=file-operations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-operations.d.ts","names":[],"sources":["../../src/context/file-operations.ts"],"sourcesContent":[],"mappings":";;AASA;AAUA;AASA;AASA;AAUA;;;AAcwB,UApDP,cAAA,CAoDO;EAKI,OAAA,EAAA,OAAA;EAQvB,IAAA,EAAA,MAAA;EAAO,OAAA,CAAA,EAAA,MAAA;EAMC,KAAA,CAAA,EAAA,MAAA;;;;;AA4ByC,UAzFrC,eAAA,CAyFqC;EA0B1B,OAAA,EAAA,OAAA;EAA0B,IAAA,EAAA,MAAA;EAAR,KAAA,CAAA,EAAA,MAAA;;AAyF9C;;;UAnMiB,aAAA;;;;;;;;UASA,mBAAA;aACJ;;;;;;;;UASI,UAAA;;;;0BAIS;;;;4CAKkB;;;;wBAKpB;;;;4BAKI;;;;;;;MAQvB;;;;;cAMQ,cAAA;;;;kBAEY;;;;8BAQW,QAAQ;;;;gDAkBU,QAAQ;;;;sBA0BlC,kBAAkB,QAAQ;;;;;;;;;iBAyFtC,wBAAA,gDAGb"}
@@ -171,4 +171,5 @@ function createNodeFileOperations(workspacePath, allowWrites = false) {
171
171
  }
172
172
 
173
173
  //#endregion
174
- export { FileOperations, createNodeFileOperations };
174
+ export { FileOperations, createNodeFileOperations };
175
+ //# sourceMappingURL=file-operations.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-operations.js","names":["fs: FileSystem","workspacePath: string","results: FileOperationResult[]","result: FileOperationResult","files: string[]"],"sources":["../../src/context/file-operations.ts"],"sourcesContent":["/**\n * File operations for workspace context\n *\n * Provides read/write operations for files in the workspace.\n */\n\n/**\n * Result of a file read operation\n */\nexport interface FileReadResult {\n success: boolean;\n path: string;\n content?: string;\n error?: string;\n}\n\n/**\n * Result of a file write operation\n */\nexport interface FileWriteResult {\n success: boolean;\n path: string;\n error?: string;\n}\n\n/**\n * File operation to perform\n */\nexport interface FileOperation {\n type: 'read' | 'write' | 'create' | 'delete';\n path: string;\n content?: string;\n}\n\n/**\n * Result of a file operation\n */\nexport interface FileOperationResult {\n operation: FileOperation;\n success: boolean;\n content?: string;\n error?: string;\n}\n\n/**\n * Interface for file system operations\n */\nexport interface FileSystem {\n /**\n * Read a file's contents\n */\n readFile(path: string): Promise<string>;\n\n /**\n * Write content to a file\n */\n writeFile(path: string, content: string): Promise<void>;\n\n /**\n * Check if a file exists\n */\n exists(path: string): Promise<boolean>;\n\n /**\n * Delete a file\n */\n deleteFile(path: string): Promise<void>;\n\n /**\n * List files in a directory\n */\n listFiles(\n directory: string,\n options?: { recursive?: boolean; pattern?: string }\n ): Promise<string[]>;\n}\n\n/**\n * File operations executor\n */\nexport class FileOperations {\n constructor(\n private readonly fs: FileSystem,\n private readonly workspacePath: string,\n private readonly allowWrites = false\n ) {}\n\n /**\n * Read a file\n */\n async read(relativePath: string): Promise<FileReadResult> {\n const fullPath = this.resolvePath(relativePath);\n\n try {\n const content = await this.fs.readFile(fullPath);\n return { success: true, path: relativePath, content };\n } catch (error) {\n return {\n success: false,\n path: relativePath,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Write to a file\n */\n async write(relativePath: string, content: string): Promise<FileWriteResult> {\n if (!this.allowWrites) {\n return {\n success: false,\n path: relativePath,\n error: 'File writes are not enabled',\n };\n }\n\n const fullPath = this.resolvePath(relativePath);\n\n try {\n await this.fs.writeFile(fullPath, content);\n return { success: true, path: relativePath };\n } catch (error) {\n return {\n success: false,\n path: relativePath,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n\n /**\n * Execute multiple file operations\n */\n async execute(operations: FileOperation[]): Promise<FileOperationResult[]> {\n const results: FileOperationResult[] = [];\n\n for (const operation of operations) {\n let result: FileOperationResult;\n\n switch (operation.type) {\n case 'read': {\n const readResult = await this.read(operation.path);\n result = {\n operation,\n success: readResult.success,\n content: readResult.content,\n error: readResult.error,\n };\n break;\n }\n\n case 'write':\n case 'create': {\n if (!operation.content) {\n result = {\n operation,\n success: false,\n error: 'Content is required for write operations',\n };\n } else {\n const writeResult = await this.write(\n operation.path,\n operation.content\n );\n result = {\n operation,\n success: writeResult.success,\n error: writeResult.error,\n };\n }\n break;\n }\n\n case 'delete': {\n if (!this.allowWrites) {\n result = {\n operation,\n success: false,\n error: 'File writes are not enabled',\n };\n } else {\n try {\n await this.fs.deleteFile(this.resolvePath(operation.path));\n result = { operation, success: true };\n } catch (error) {\n result = {\n operation,\n success: false,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n }\n break;\n }\n\n default:\n result = {\n operation,\n success: false,\n error: `Unknown operation type: ${(operation as FileOperation).type}`,\n };\n }\n\n results.push(result);\n }\n\n return results;\n }\n\n /**\n * Resolve a relative path to an absolute path\n */\n private resolvePath(relativePath: string): string {\n // Prevent path traversal\n const normalized = relativePath.replace(/\\.\\./g, '').replace(/^\\//, '');\n return `${this.workspacePath}/${normalized}`;\n }\n}\n\n/**\n * Create a file operations instance with Node.js fs\n */\nexport function createNodeFileOperations(\n workspacePath: string,\n allowWrites = false\n): FileOperations {\n // Dynamic import to avoid issues in browser environments\n const fs: FileSystem = {\n async readFile(path: string): Promise<string> {\n const { readFile } = await import('node:fs/promises');\n return readFile(path, 'utf-8');\n },\n async writeFile(path: string, content: string): Promise<void> {\n const { writeFile, mkdir } = await import('node:fs/promises');\n const { dirname } = await import('node:path');\n await mkdir(dirname(path), { recursive: true });\n await writeFile(path, content, 'utf-8');\n },\n async exists(path: string): Promise<boolean> {\n const { access } = await import('node:fs/promises');\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n },\n async deleteFile(path: string): Promise<void> {\n const { unlink } = await import('node:fs/promises');\n await unlink(path);\n },\n async listFiles(\n directory: string,\n options?: { recursive?: boolean; pattern?: string }\n ): Promise<string[]> {\n const { readdir } = await import('node:fs/promises');\n const { join } = await import('node:path');\n\n const files: string[] = [];\n const entries = await readdir(directory, { withFileTypes: true });\n\n for (const entry of entries) {\n const fullPath = join(directory, entry.name);\n if (entry.isDirectory() && options?.recursive) {\n const subFiles = await this.listFiles(fullPath, options);\n files.push(...subFiles);\n } else if (entry.isFile()) {\n if (\n !options?.pattern ||\n entry.name.match(new RegExp(options.pattern))\n ) {\n files.push(fullPath);\n }\n }\n }\n\n return files;\n },\n };\n\n return new FileOperations(fs, workspacePath, allowWrites);\n}\n"],"mappings":"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"}
@@ -113,4 +113,5 @@ declare class WorkspaceContext {
113
113
  */
114
114
  declare function createWorkspaceContext(path: string, options?: Partial<WorkspaceContextConfig>): Promise<WorkspaceContext>;
115
115
  //#endregion
116
- export { FileInfo, SpecInfo, WorkspaceContext, WorkspaceContextConfig, WorkspaceSummary, createWorkspaceContext };
116
+ export { FileInfo, SpecInfo, WorkspaceContext, WorkspaceContextConfig, WorkspaceSummary, createWorkspaceContext };
117
+ //# sourceMappingURL=workspace-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-context.d.ts","names":[],"sources":["../../src/context/workspace-context.ts"],"sourcesContent":[],"mappings":";;AAUA;AAYA;AAYA;AAoBA;AAgBA;;;;AAkCc,UA9FG,QAAA,CA8FH;EAOI,IAAA,EAAA,MAAA;EAOA,OAAA,EAAA,MAAA;EAOF,IAAA,EAAA,SAAA,GAAA,OAAA,GAAA,OAAA,GAAA,cAAA;EA8DY,IAAA,EAAA,MAAA;EAaA,WAAA,CAAA,EAAA,MAAA;EAAQ,IAAA,CAAA,EAAA,MAAA,EAAA;AAapC;;;;AAGG,UAlMc,QAAA,CAkMd;EAAO,IAAA,EAAA,MAAA;;;;;;;;;;UAtLO,gBAAA;;;;;;;;;;;;;;;;;;;UAoBA,sBAAA;;;;;;;;;;;;;;;cAgBJ,gBAAA;;;;;;sBAQS;;;;gBAQA;;;;cAWR;;;;cAOA;;;;kBAOI;;;;kBAOA;;;;gBAOF;;;;;;;;4BA8DY;;;;4BAaA;;;;;iBAaN,sBAAA,yBAEV,QAAQ,0BACjB,QAAQ"}
@@ -120,4 +120,5 @@ async function createWorkspaceContext(path, options) {
120
120
  }
121
121
 
122
122
  //#endregion
123
- export { WorkspaceContext, createWorkspaceContext };
123
+ export { WorkspaceContext, createWorkspaceContext };
124
+ //# sourceMappingURL=workspace-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workspace-context.js","names":["parts: string[]"],"sources":["../../src/context/workspace-context.ts"],"sourcesContent":["/**\n * Workspace context management\n *\n * Provides access to specs, files, and codebase information\n * for context-aware AI chat assistance.\n */\n\n/**\n * Spec information for context\n */\nexport interface SpecInfo {\n name: string;\n version: number;\n type: 'command' | 'query' | 'event' | 'presentation';\n path: string;\n description?: string;\n tags?: string[];\n}\n\n/**\n * File information for context\n */\nexport interface FileInfo {\n path: string;\n relativePath: string;\n name: string;\n extension: string;\n size: number;\n isSpec: boolean;\n}\n\n/**\n * Workspace summary for context\n */\nexport interface WorkspaceSummary {\n name: string;\n path: string;\n specs: {\n total: number;\n commands: number;\n queries: number;\n events: number;\n presentations: number;\n };\n files: {\n total: number;\n typescript: number;\n specFiles: number;\n };\n}\n\n/**\n * Configuration for workspace context\n */\nexport interface WorkspaceContextConfig {\n /** Root path of the workspace */\n workspacePath: string;\n /** File patterns to include */\n includePatterns?: string[];\n /** File patterns to exclude */\n excludePatterns?: string[];\n /** Maximum file size to read (bytes) */\n maxFileSize?: number;\n /** Whether to enable file writes */\n allowWrites?: boolean;\n}\n\n/**\n * Workspace context for AI chat\n */\nexport class WorkspaceContext {\n readonly workspacePath: string;\n readonly allowWrites: boolean;\n\n private specs: SpecInfo[] = [];\n private files: FileInfo[] = [];\n private initialized = false;\n\n constructor(config: WorkspaceContextConfig) {\n this.workspacePath = config.workspacePath;\n this.allowWrites = config.allowWrites ?? false;\n }\n\n /**\n * Initialize the workspace context by scanning files\n */\n async initialize(): Promise<void> {\n if (this.initialized) return;\n\n // This would scan the workspace for specs and files\n // For now, we just mark as initialized\n this.initialized = true;\n }\n\n /**\n * Get all discovered specs\n */\n getSpecs(): SpecInfo[] {\n return this.specs;\n }\n\n /**\n * Get all discovered files\n */\n getFiles(): FileInfo[] {\n return this.files;\n }\n\n /**\n * Add specs to the context\n */\n addSpecs(specs: SpecInfo[]): void {\n this.specs.push(...specs);\n }\n\n /**\n * Add files to the context\n */\n addFiles(files: FileInfo[]): void {\n this.files.push(...files);\n }\n\n /**\n * Get a summary of the workspace for context\n */\n getSummary(): WorkspaceSummary {\n const commands = this.specs.filter((s) => s.type === 'command').length;\n const queries = this.specs.filter((s) => s.type === 'query').length;\n const events = this.specs.filter((s) => s.type === 'event').length;\n const presentations = this.specs.filter(\n (s) => s.type === 'presentation'\n ).length;\n\n const tsFiles = this.files.filter((f) => f.extension === '.ts').length;\n const specFiles = this.files.filter((f) => f.isSpec).length;\n\n return {\n name: this.workspacePath.split('/').pop() ?? 'workspace',\n path: this.workspacePath,\n specs: {\n total: this.specs.length,\n commands,\n queries,\n events,\n presentations,\n },\n files: {\n total: this.files.length,\n typescript: tsFiles,\n specFiles,\n },\n };\n }\n\n /**\n * Get a context summary for LLM prompts\n */\n getContextSummary(): string {\n const summary = this.getSummary();\n\n const parts: string[] = [\n `Workspace: ${summary.name}`,\n `Path: ${summary.path}`,\n '',\n '### Specs',\n `- Commands: ${summary.specs.commands}`,\n `- Queries: ${summary.specs.queries}`,\n `- Events: ${summary.specs.events}`,\n `- Presentations: ${summary.specs.presentations}`,\n ];\n\n if (this.specs.length > 0) {\n parts.push('', '### Available Specs');\n for (const spec of this.specs.slice(0, 20)) {\n parts.push(`- ${spec.name} (${spec.type})`);\n }\n if (this.specs.length > 20) {\n parts.push(`- ... and ${this.specs.length - 20} more`);\n }\n }\n\n return parts.join('\\n');\n }\n\n /**\n * Find specs matching a query\n */\n findSpecs(query: string): SpecInfo[] {\n const lowerQuery = query.toLowerCase();\n return this.specs.filter(\n (s) =>\n s.name.toLowerCase().includes(lowerQuery) ||\n s.description?.toLowerCase().includes(lowerQuery) ||\n s.tags?.some((t) => t.toLowerCase().includes(lowerQuery))\n );\n }\n\n /**\n * Find files matching a query\n */\n findFiles(query: string): FileInfo[] {\n const lowerQuery = query.toLowerCase();\n return this.files.filter(\n (f) =>\n f.path.toLowerCase().includes(lowerQuery) ||\n f.name.toLowerCase().includes(lowerQuery)\n );\n }\n}\n\n/**\n * Create a workspace context from a path\n */\nexport async function createWorkspaceContext(\n path: string,\n options?: Partial<WorkspaceContextConfig>\n): Promise<WorkspaceContext> {\n const context = new WorkspaceContext({\n workspacePath: path,\n ...options,\n });\n await context.initialize();\n return context;\n}\n"],"mappings":";;;;AAsEA,IAAa,mBAAb,MAA8B;CAC5B,AAAS;CACT,AAAS;CAET,AAAQ,QAAoB,EAAE;CAC9B,AAAQ,QAAoB,EAAE;CAC9B,AAAQ,cAAc;CAEtB,YAAY,QAAgC;AAC1C,OAAK,gBAAgB,OAAO;AAC5B,OAAK,cAAc,OAAO,eAAe;;;;;CAM3C,MAAM,aAA4B;AAChC,MAAI,KAAK,YAAa;AAItB,OAAK,cAAc;;;;;CAMrB,WAAuB;AACrB,SAAO,KAAK;;;;;CAMd,WAAuB;AACrB,SAAO,KAAK;;;;;CAMd,SAAS,OAAyB;AAChC,OAAK,MAAM,KAAK,GAAG,MAAM;;;;;CAM3B,SAAS,OAAyB;AAChC,OAAK,MAAM,KAAK,GAAG,MAAM;;;;;CAM3B,aAA+B;EAC7B,MAAM,WAAW,KAAK,MAAM,QAAQ,MAAM,EAAE,SAAS,UAAU,CAAC;EAChE,MAAM,UAAU,KAAK,MAAM,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC;EAC7D,MAAM,SAAS,KAAK,MAAM,QAAQ,MAAM,EAAE,SAAS,QAAQ,CAAC;EAC5D,MAAM,gBAAgB,KAAK,MAAM,QAC9B,MAAM,EAAE,SAAS,eACnB,CAAC;EAEF,MAAM,UAAU,KAAK,MAAM,QAAQ,MAAM,EAAE,cAAc,MAAM,CAAC;EAChE,MAAM,YAAY,KAAK,MAAM,QAAQ,MAAM,EAAE,OAAO,CAAC;AAErD,SAAO;GACL,MAAM,KAAK,cAAc,MAAM,IAAI,CAAC,KAAK,IAAI;GAC7C,MAAM,KAAK;GACX,OAAO;IACL,OAAO,KAAK,MAAM;IAClB;IACA;IACA;IACA;IACD;GACD,OAAO;IACL,OAAO,KAAK,MAAM;IAClB,YAAY;IACZ;IACD;GACF;;;;;CAMH,oBAA4B;EAC1B,MAAM,UAAU,KAAK,YAAY;EAEjC,MAAMA,QAAkB;GACtB,cAAc,QAAQ;GACtB,SAAS,QAAQ;GACjB;GACA;GACA,eAAe,QAAQ,MAAM;GAC7B,cAAc,QAAQ,MAAM;GAC5B,aAAa,QAAQ,MAAM;GAC3B,oBAAoB,QAAQ,MAAM;GACnC;AAED,MAAI,KAAK,MAAM,SAAS,GAAG;AACzB,SAAM,KAAK,IAAI,sBAAsB;AACrC,QAAK,MAAM,QAAQ,KAAK,MAAM,MAAM,GAAG,GAAG,CACxC,OAAM,KAAK,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,GAAG;AAE7C,OAAI,KAAK,MAAM,SAAS,GACtB,OAAM,KAAK,aAAa,KAAK,MAAM,SAAS,GAAG,OAAO;;AAI1D,SAAO,MAAM,KAAK,KAAK;;;;;CAMzB,UAAU,OAA2B;EACnC,MAAM,aAAa,MAAM,aAAa;AACtC,SAAO,KAAK,MAAM,QACf,MACC,EAAE,KAAK,aAAa,CAAC,SAAS,WAAW,IACzC,EAAE,aAAa,aAAa,CAAC,SAAS,WAAW,IACjD,EAAE,MAAM,MAAM,MAAM,EAAE,aAAa,CAAC,SAAS,WAAW,CAAC,CAC5D;;;;;CAMH,UAAU,OAA2B;EACnC,MAAM,aAAa,MAAM,aAAa;AACtC,SAAO,KAAK,MAAM,QACf,MACC,EAAE,KAAK,aAAa,CAAC,SAAS,WAAW,IACzC,EAAE,KAAK,aAAa,CAAC,SAAS,WAAW,CAC5C;;;;;;AAOL,eAAsB,uBACpB,MACA,SAC2B;CAC3B,MAAM,UAAU,IAAI,iBAAiB;EACnC,eAAe;EACf,GAAG;EACJ,CAAC;AACF,OAAM,QAAQ,YAAY;AAC1B,QAAO"}
@@ -69,4 +69,5 @@ declare class ChatService {
69
69
  */
70
70
  declare function createChatService(config: ChatServiceConfig): ChatService;
71
71
  //#endregion
72
- export { ChatService, ChatServiceConfig, createChatService };
72
+ export { ChatService, ChatServiceConfig, createChatService };
73
+ //# sourceMappingURL=chat-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-service.d.ts","names":[],"sources":["../../src/core/chat-service.ts"],"sourcesContent":[],"mappings":";;;;;;;;;AAoBA;AAEY,UAFK,iBAAA,CAEL;EAEA;EAEF,QAAA,EAJE,QAIF;EAAiB;EA8Bd,OAAA,CAAA,EAhCD,gBAgCY;EAWF;EAYA,KAAA,CAAA,EArDZ,iBAqDY;EAA6B;EAAR,YAAA,CAAA,EAAA,MAAA;EA6EnB;EAA6B,kBAAA,CAAA,EAAA,MAAA;EAAR;EAkGhC,OAAA,CAAA,EAAA,CAAA,KAAA,EAAA;IAAR,WAAA,EAAA,MAAA;IAUS,YAAA,EAAA,MAAA;EAAR,CAAA,EAAA,GAAA,IAAA;;;AA2DN;;cA3Qa,WAAA;;;;;;;sBAWS;;;;gBAYA,qBAAqB,QAAQ;;;;kBA6E3B,qBAAqB,QAAQ;;;;2CAkGhD,QAAQ;;;;;;;MAUP,QAAQ;;;;8CAUsC;;;;;;;;;iBAiDpC,iBAAA,SAA0B,oBAAoB"}
@@ -220,4 +220,5 @@ function createChatService(config) {
220
220
  }
221
221
 
222
222
  //#endregion
223
- export { ChatService, createChatService };
223
+ export { ChatService, createChatService };
224
+ //# sourceMappingURL=chat-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chat-service.js","names":["conversation: ChatConversation"],"sources":["../../src/core/chat-service.ts"],"sourcesContent":["/**\n * Main chat orchestration service\n */\nimport { generateText, streamText } from 'ai';\nimport type { Provider as ChatProvider } from '@lssm/lib.ai-providers';\nimport type { WorkspaceContext } from '../context/workspace-context';\nimport type { ConversationStore } from './conversation-store';\nimport { InMemoryConversationStore } from './conversation-store';\nimport type {\n ChatConversation,\n ChatMessage,\n ChatStreamChunk,\n SendMessageOptions,\n SendMessageResult,\n StreamMessageResult,\n} from './message-types';\n\n/**\n * Configuration for ChatService\n */\nexport interface ChatServiceConfig {\n /** LLM provider to use */\n provider: ChatProvider;\n /** Optional workspace context for code-aware chat */\n context?: WorkspaceContext;\n /** Optional conversation store (defaults to in-memory) */\n store?: ConversationStore;\n /** Default system prompt */\n systemPrompt?: string;\n /** Maximum conversation history to include */\n maxHistoryMessages?: number;\n /** Callback for usage tracking */\n onUsage?: (usage: { inputTokens: number; outputTokens: number }) => void;\n}\n\n/**\n * Default system prompt for ContractSpec vibe coding\n */\nconst DEFAULT_SYSTEM_PROMPT = `You are ContractSpec AI, an expert coding assistant specialized in ContractSpec development.\n\nYour capabilities:\n- Help users create, modify, and understand ContractSpec specifications\n- Generate code that follows ContractSpec patterns and best practices\n- Explain concepts from the ContractSpec documentation\n- Suggest improvements and identify issues in specs and implementations\n\nGuidelines:\n- Be concise but thorough\n- Provide code examples when helpful\n- Reference relevant ContractSpec concepts and patterns\n- Ask clarifying questions when the user's intent is unclear\n- When suggesting code changes, explain the rationale`;\n\n/**\n * Main chat service for AI-powered conversations\n */\nexport class ChatService {\n private readonly provider: ChatProvider;\n private readonly context?: WorkspaceContext;\n private readonly store: ConversationStore;\n private readonly systemPrompt: string;\n private readonly maxHistoryMessages: number;\n private readonly onUsage?: (usage: {\n inputTokens: number;\n outputTokens: number;\n }) => void;\n\n constructor(config: ChatServiceConfig) {\n this.provider = config.provider;\n this.context = config.context;\n this.store = config.store ?? new InMemoryConversationStore();\n this.systemPrompt = config.systemPrompt ?? DEFAULT_SYSTEM_PROMPT;\n this.maxHistoryMessages = config.maxHistoryMessages ?? 20;\n this.onUsage = config.onUsage;\n }\n\n /**\n * Send a message and get a complete response\n */\n async send(options: SendMessageOptions): Promise<SendMessageResult> {\n // Get or create conversation\n let conversation: ChatConversation;\n if (options.conversationId) {\n const existing = await this.store.get(options.conversationId);\n if (!existing) {\n throw new Error(`Conversation ${options.conversationId} not found`);\n }\n conversation = existing;\n } else {\n conversation = await this.store.create({\n status: 'active',\n provider: this.provider.name,\n model: this.provider.model,\n messages: [],\n workspacePath: this.context?.workspacePath,\n });\n }\n\n // Add user message\n const userMessage = await this.store.appendMessage(conversation.id, {\n role: 'user',\n content: options.content,\n status: 'completed',\n attachments: options.attachments,\n });\n\n // Build prompt from messages\n const prompt = this.buildPrompt(conversation, options);\n\n // Get the language model\n const model = this.provider.getModel();\n\n try {\n // Generate response\n const result = await generateText({\n model,\n prompt,\n system: this.systemPrompt,\n });\n\n // Save assistant message\n const assistantMessage = await this.store.appendMessage(conversation.id, {\n role: 'assistant',\n content: result.text,\n status: 'completed',\n });\n\n // Refresh conversation\n const updatedConversation = await this.store.get(conversation.id);\n if (!updatedConversation) {\n throw new Error('Conversation lost after update');\n }\n\n return {\n message: assistantMessage,\n conversation: updatedConversation,\n };\n } catch (error) {\n // Save error message\n await this.store.appendMessage(conversation.id, {\n role: 'assistant',\n content: '',\n status: 'error',\n error: {\n code: 'generation_failed',\n message: error instanceof Error ? error.message : String(error),\n },\n });\n\n throw error;\n }\n }\n\n /**\n * Send a message and get a streaming response\n */\n async stream(options: SendMessageOptions): Promise<StreamMessageResult> {\n // Get or create conversation\n let conversation: ChatConversation;\n if (options.conversationId) {\n const existing = await this.store.get(options.conversationId);\n if (!existing) {\n throw new Error(`Conversation ${options.conversationId} not found`);\n }\n conversation = existing;\n } else {\n conversation = await this.store.create({\n status: 'active',\n provider: this.provider.name,\n model: this.provider.model,\n messages: [],\n workspacePath: this.context?.workspacePath,\n });\n }\n\n // Add user message\n await this.store.appendMessage(conversation.id, {\n role: 'user',\n content: options.content,\n status: 'completed',\n attachments: options.attachments,\n });\n\n // Create placeholder for assistant message\n const assistantMessage = await this.store.appendMessage(conversation.id, {\n role: 'assistant',\n content: '',\n status: 'streaming',\n });\n\n // Build prompt\n const prompt = this.buildPrompt(conversation, options);\n\n // Get the language model\n const model = this.provider.getModel();\n\n // Create async generator for streaming\n const self = this;\n async function* streamGenerator(): AsyncIterable<ChatStreamChunk> {\n let fullContent = '';\n\n try {\n const result = streamText({\n model,\n prompt,\n system: self.systemPrompt,\n });\n\n for await (const chunk of result.textStream) {\n fullContent += chunk;\n yield { type: 'text', content: chunk };\n }\n\n // Update message with final content\n await self.store.updateMessage(conversation.id, assistantMessage.id, {\n content: fullContent,\n status: 'completed',\n });\n\n yield {\n type: 'done',\n };\n } catch (error) {\n await self.store.updateMessage(conversation.id, assistantMessage.id, {\n content: fullContent,\n status: 'error',\n error: {\n code: 'stream_failed',\n message: error instanceof Error ? error.message : String(error),\n },\n });\n\n yield {\n type: 'error',\n error: {\n code: 'stream_failed',\n message: error instanceof Error ? error.message : String(error),\n },\n };\n }\n }\n\n return {\n conversationId: conversation.id,\n messageId: assistantMessage.id,\n stream: streamGenerator(),\n };\n }\n\n /**\n * Get a conversation by ID\n */\n async getConversation(\n conversationId: string\n ): Promise<ChatConversation | null> {\n return this.store.get(conversationId);\n }\n\n /**\n * List conversations\n */\n async listConversations(options?: {\n limit?: number;\n offset?: number;\n }): Promise<ChatConversation[]> {\n return this.store.list({\n status: 'active',\n ...options,\n });\n }\n\n /**\n * Delete a conversation\n */\n async deleteConversation(conversationId: string): Promise<boolean> {\n return this.store.delete(conversationId);\n }\n\n /**\n * Build prompt string for LLM\n */\n private buildPrompt(\n conversation: ChatConversation,\n options: SendMessageOptions\n ): string {\n let prompt = '';\n\n // Add conversation history (limited)\n const historyStart = Math.max(\n 0,\n conversation.messages.length - this.maxHistoryMessages\n );\n for (let i = historyStart; i < conversation.messages.length; i++) {\n const msg = conversation.messages[i];\n if (!msg) continue;\n if (msg.role === 'user' || msg.role === 'assistant') {\n prompt += `${msg.role === 'user' ? 'User' : 'Assistant'}: ${msg.content}\\n\\n`;\n }\n }\n\n // Add current message with attachments\n let content = options.content;\n if (options.attachments?.length) {\n const attachmentInfo = options.attachments\n .map((a) => {\n if (a.type === 'file' || a.type === 'code') {\n return `\\n\\n### ${a.name}\\n\\`\\`\\`\\n${a.content}\\n\\`\\`\\``;\n }\n return `\\n\\n[Attachment: ${a.name}]`;\n })\n .join('');\n content += attachmentInfo;\n }\n\n prompt += `User: ${content}\\n\\nAssistant:`;\n\n return prompt;\n }\n}\n\n/**\n * Create a chat service with the given configuration\n */\nexport function createChatService(config: ChatServiceConfig): ChatService {\n return new ChatService(config);\n}\n"],"mappings":"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"}
@@ -70,4 +70,5 @@ declare class InMemoryConversationStore implements ConversationStore {
70
70
  */
71
71
  declare function createInMemoryConversationStore(): ConversationStore;
72
72
  //#endregion
73
- export { ConversationStore, InMemoryConversationStore, createInMemoryConversationStore };
73
+ export { ConversationStore, InMemoryConversationStore, createInMemoryConversationStore };
74
+ //# sourceMappingURL=conversation-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-store.d.ts","names":[],"sources":["../../src/core/conversation-store.ts"],"sourcesContent":[],"mappings":";;;;;;;AAsBkB,UAVD,iBAAA,CAUC;EACL;;;EAQP,GAAA,CAAA,cAAA,EAAA,MAAA,CAAA,EAfyB,OAezB,CAfiC,gBAejC,GAAA,IAAA,CAAA;EADO;;;EAWP,MAAA,CAAA,YAAA,EAnBY,IAmBZ,CAnBiB,gBAmBjB,EAAA,IAAA,GAAA,WAAA,GAAA,WAAA,CAAA,CAAA,EAlBD,OAkBC,CAlBO,gBAkBP,CAAA;EADO;;;EAYQ,MAAA,CAAA,cAAA,EAAA,MAAA,EAAA,OAAA,EAtBR,OAsBQ,CArBf,IAqBe,CArBV,gBAqBU,EAAA,OAAA,GAAA,QAAA,GAAA,SAAA,GAAA,UAAA,CAAA,CAAA,CAAA,EAnBhB,OAmBgB,CAnBR,gBAmBQ,GAAA,IAAA,CAAA;EAAR;;;EAMqB,aAAA,CAAA,cAAA,EAAA,MAAA,EAAA,OAAA,EAlBrB,IAkBqB,CAjB5B,WAiB4B,EAAA,IAAA,GAAA,gBAAA,GAAA,WAAA,GAAA,WAAA,CAAA,CAAA,EAd7B,OAc6B,CAdrB,WAcqB,CAAA;EAMrB;;;EAQoC,aAAA,CAAA,cAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EApBpC,OAoBoC,CApB5B,WAoB4B,CAAA,CAAA,EAnB5C,OAmB4C,CAnBpC,WAmBoC,GAAA,IAAA,CAAA;EAAR;;AAazC;EAG6C,MAAA,CAAA,cAAA,EAAA,MAAA,CAAA,EA9BX,OA8BW,CAAA,OAAA,CAAA;EAAR;;;EAMxB,IAAA,CAAA,OAcA,CAdA,EAAA;IAAR,MAAA,CAAA,EA9BQ,kBA8BR;IAeM,KAAA,CAAA,EAAA,MAAA;IAAL,MAAA,CAAA,EAAA,MAAA;EADO,CAAA,CAAA,EAzCP,OAyCO,CAzCC,gBAyCD,EAAA,CAAA;EAGA;;;EAeA,MAAA,CAAA,KAAA,EAAA,MAAA,EAAA,KAAA,CAAA,EAAA,MAAA,CAAA,EAtD4B,OAsD5B,CAtDoC,gBAsDpC,EAAA,CAAA;;;;;AA4BA,cArEA,yBAAA,YAAqC,iBAqErC,CAAA;EAAR,iBAAA,aAAA;EAsBmC,GAAA,CAAA,cAAA,EAAA,MAAA,CAAA,EAxFH,OAwFG,CAxFK,gBAwFL,GAAA,IAAA,CAAA;EAK3B,MAAA,CAAA,YAAA,EAxFK,IAwFL,CAxFU,gBAwFV,EAAA,IAAA,GAAA,WAAA,GAAA,WAAA,CAAA,CAAA,EAvFR,OAuFQ,CAvFA,gBAuFA,CAAA;EAGC,MAAA,CAAA,cAAA,EAAA,MAAA,EAAA,OAAA,EA5ED,OA4EC,CA3ER,IA2EQ,CA3EH,gBA2EG,EAAA,OAAA,GAAA,QAAA,GAAA,SAAA,GAAA,UAAA,CAAA,CAAA,CAAA,EAzET,OAyES,CAzED,gBAyEC,GAAA,IAAA,CAAA;EAAR,aAAA,CAAA,cAAA,EAAA,MAAA,EAAA,OAAA,EA1DO,IA0DP,CAzDA,WAyDA,EAAA,IAAA,GAAA,gBAAA,GAAA,WAAA,GAAA,WAAA,CAAA,CAAA,EAtDD,OAsDC,CAtDO,WAsDP,CAAA;EAe6C,aAAA,CAAA,cAAA,EAAA,MAAA,EAAA,SAAA,EAAA,MAAA,EAAA,OAAA,EA9CtC,OA8CsC,CA9C9B,WA8C8B,CAAA,CAAA,EA7C9C,OA6C8C,CA7CtC,WA6CsC,GAAA,IAAA,CAAA;EAAR,MAAA,CAAA,cAAA,EAAA,MAAA,CAAA,EAvBH,OAuBG,CAAA,OAAA,CAAA;EAlHO,IAAA,CAAA,QAAA,EAAA;IAAiB,MAAA,CAAA,EAgGtD,kBAhGsD;IAsJnD,KAAA,CAAA,EAAA,MAAA;;MAnDV,QAAQ;yCAe6B,QAAQ;;;;;;;;;iBAoCnC,+BAAA,CAAA,GAAmC"}
@@ -105,4 +105,5 @@ function createInMemoryConversationStore() {
105
105
  }
106
106
 
107
107
  //#endregion
108
- export { InMemoryConversationStore, createInMemoryConversationStore };
108
+ export { InMemoryConversationStore, createInMemoryConversationStore };
109
+ //# sourceMappingURL=conversation-store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-store.js","names":["fullConversation: ChatConversation","fullMessage: ChatMessage","results: ChatConversation[]"],"sources":["../../src/core/conversation-store.ts"],"sourcesContent":["/**\n * Conversation storage interface and implementations\n */\nimport type {\n ChatConversation,\n ChatMessage,\n ConversationStatus,\n} from './message-types';\n\n/**\n * Interface for conversation persistence\n */\nexport interface ConversationStore {\n /**\n * Get a conversation by ID\n */\n get(conversationId: string): Promise<ChatConversation | null>;\n\n /**\n * Create a new conversation\n */\n create(\n conversation: Omit<ChatConversation, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<ChatConversation>;\n\n /**\n * Update conversation properties\n */\n update(\n conversationId: string,\n updates: Partial<\n Pick<ChatConversation, 'title' | 'status' | 'summary' | 'metadata'>\n >\n ): Promise<ChatConversation | null>;\n\n /**\n * Append a message to a conversation\n */\n appendMessage(\n conversationId: string,\n message: Omit<\n ChatMessage,\n 'id' | 'conversationId' | 'createdAt' | 'updatedAt'\n >\n ): Promise<ChatMessage>;\n\n /**\n * Update a message in a conversation\n */\n updateMessage(\n conversationId: string,\n messageId: string,\n updates: Partial<ChatMessage>\n ): Promise<ChatMessage | null>;\n\n /**\n * Delete a conversation\n */\n delete(conversationId: string): Promise<boolean>;\n\n /**\n * List conversations with optional filters\n */\n list(options?: {\n status?: ConversationStatus;\n limit?: number;\n offset?: number;\n }): Promise<ChatConversation[]>;\n\n /**\n * Search conversations by content\n */\n search(query: string, limit?: number): Promise<ChatConversation[]>;\n}\n\n/**\n * Generate a unique ID\n */\nfunction generateId(prefix: string): string {\n return `${prefix}_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`;\n}\n\n/**\n * In-memory conversation store for development and testing\n */\nexport class InMemoryConversationStore implements ConversationStore {\n private readonly conversations = new Map<string, ChatConversation>();\n\n async get(conversationId: string): Promise<ChatConversation | null> {\n return this.conversations.get(conversationId) ?? null;\n }\n\n async create(\n conversation: Omit<ChatConversation, 'id' | 'createdAt' | 'updatedAt'>\n ): Promise<ChatConversation> {\n const now = new Date();\n const fullConversation: ChatConversation = {\n ...conversation,\n id: generateId('conv'),\n createdAt: now,\n updatedAt: now,\n };\n this.conversations.set(fullConversation.id, fullConversation);\n return fullConversation;\n }\n\n async update(\n conversationId: string,\n updates: Partial<\n Pick<ChatConversation, 'title' | 'status' | 'summary' | 'metadata'>\n >\n ): Promise<ChatConversation | null> {\n const conversation = this.conversations.get(conversationId);\n if (!conversation) return null;\n\n const updated = {\n ...conversation,\n ...updates,\n updatedAt: new Date(),\n };\n this.conversations.set(conversationId, updated);\n return updated;\n }\n\n async appendMessage(\n conversationId: string,\n message: Omit<\n ChatMessage,\n 'id' | 'conversationId' | 'createdAt' | 'updatedAt'\n >\n ): Promise<ChatMessage> {\n const conversation = this.conversations.get(conversationId);\n if (!conversation) {\n throw new Error(`Conversation ${conversationId} not found`);\n }\n\n const now = new Date();\n const fullMessage: ChatMessage = {\n ...message,\n id: generateId('msg'),\n conversationId,\n createdAt: now,\n updatedAt: now,\n };\n\n conversation.messages.push(fullMessage);\n conversation.updatedAt = now;\n return fullMessage;\n }\n\n async updateMessage(\n conversationId: string,\n messageId: string,\n updates: Partial<ChatMessage>\n ): Promise<ChatMessage | null> {\n const conversation = this.conversations.get(conversationId);\n if (!conversation) return null;\n\n const messageIndex = conversation.messages.findIndex(\n (m) => m.id === messageId\n );\n if (messageIndex === -1) return null;\n\n const message = conversation.messages[messageIndex];\n if (!message) return null;\n\n const updated = {\n ...message,\n ...updates,\n updatedAt: new Date(),\n };\n conversation.messages[messageIndex] = updated;\n conversation.updatedAt = new Date();\n return updated;\n }\n\n async delete(conversationId: string): Promise<boolean> {\n return this.conversations.delete(conversationId);\n }\n\n async list(options?: {\n status?: ConversationStatus;\n limit?: number;\n offset?: number;\n }): Promise<ChatConversation[]> {\n let results = Array.from(this.conversations.values());\n\n if (options?.status) {\n results = results.filter((c) => c.status === options.status);\n }\n\n // Sort by updatedAt descending\n results.sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime());\n\n const offset = options?.offset ?? 0;\n const limit = options?.limit ?? 100;\n return results.slice(offset, offset + limit);\n }\n\n async search(query: string, limit = 20): Promise<ChatConversation[]> {\n const lowerQuery = query.toLowerCase();\n const results: ChatConversation[] = [];\n\n for (const conversation of this.conversations.values()) {\n // Search in title\n if (conversation.title?.toLowerCase().includes(lowerQuery)) {\n results.push(conversation);\n continue;\n }\n\n // Search in messages\n const hasMatch = conversation.messages.some((m) =>\n m.content.toLowerCase().includes(lowerQuery)\n );\n if (hasMatch) {\n results.push(conversation);\n }\n\n if (results.length >= limit) break;\n }\n\n return results;\n }\n\n /**\n * Clear all conversations (for testing)\n */\n clear(): void {\n this.conversations.clear();\n }\n}\n\n/**\n * Create an in-memory conversation store\n */\nexport function createInMemoryConversationStore(): ConversationStore {\n return new InMemoryConversationStore();\n}\n"],"mappings":";;;;AA8EA,SAAS,WAAW,QAAwB;AAC1C,QAAO,GAAG,OAAO,GAAG,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,GAAG;;;;;AAM3E,IAAa,4BAAb,MAAoE;CAClE,AAAiB,gCAAgB,IAAI,KAA+B;CAEpE,MAAM,IAAI,gBAA0D;AAClE,SAAO,KAAK,cAAc,IAAI,eAAe,IAAI;;CAGnD,MAAM,OACJ,cAC2B;EAC3B,MAAM,sBAAM,IAAI,MAAM;EACtB,MAAMA,mBAAqC;GACzC,GAAG;GACH,IAAI,WAAW,OAAO;GACtB,WAAW;GACX,WAAW;GACZ;AACD,OAAK,cAAc,IAAI,iBAAiB,IAAI,iBAAiB;AAC7D,SAAO;;CAGT,MAAM,OACJ,gBACA,SAGkC;EAClC,MAAM,eAAe,KAAK,cAAc,IAAI,eAAe;AAC3D,MAAI,CAAC,aAAc,QAAO;EAE1B,MAAM,UAAU;GACd,GAAG;GACH,GAAG;GACH,2BAAW,IAAI,MAAM;GACtB;AACD,OAAK,cAAc,IAAI,gBAAgB,QAAQ;AAC/C,SAAO;;CAGT,MAAM,cACJ,gBACA,SAIsB;EACtB,MAAM,eAAe,KAAK,cAAc,IAAI,eAAe;AAC3D,MAAI,CAAC,aACH,OAAM,IAAI,MAAM,gBAAgB,eAAe,YAAY;EAG7D,MAAM,sBAAM,IAAI,MAAM;EACtB,MAAMC,cAA2B;GAC/B,GAAG;GACH,IAAI,WAAW,MAAM;GACrB;GACA,WAAW;GACX,WAAW;GACZ;AAED,eAAa,SAAS,KAAK,YAAY;AACvC,eAAa,YAAY;AACzB,SAAO;;CAGT,MAAM,cACJ,gBACA,WACA,SAC6B;EAC7B,MAAM,eAAe,KAAK,cAAc,IAAI,eAAe;AAC3D,MAAI,CAAC,aAAc,QAAO;EAE1B,MAAM,eAAe,aAAa,SAAS,WACxC,MAAM,EAAE,OAAO,UACjB;AACD,MAAI,iBAAiB,GAAI,QAAO;EAEhC,MAAM,UAAU,aAAa,SAAS;AACtC,MAAI,CAAC,QAAS,QAAO;EAErB,MAAM,UAAU;GACd,GAAG;GACH,GAAG;GACH,2BAAW,IAAI,MAAM;GACtB;AACD,eAAa,SAAS,gBAAgB;AACtC,eAAa,4BAAY,IAAI,MAAM;AACnC,SAAO;;CAGT,MAAM,OAAO,gBAA0C;AACrD,SAAO,KAAK,cAAc,OAAO,eAAe;;CAGlD,MAAM,KAAK,SAIqB;EAC9B,IAAI,UAAU,MAAM,KAAK,KAAK,cAAc,QAAQ,CAAC;AAErD,MAAI,SAAS,OACX,WAAU,QAAQ,QAAQ,MAAM,EAAE,WAAW,QAAQ,OAAO;AAI9D,UAAQ,MAAM,GAAG,MAAM,EAAE,UAAU,SAAS,GAAG,EAAE,UAAU,SAAS,CAAC;EAErE,MAAM,SAAS,SAAS,UAAU;EAClC,MAAM,QAAQ,SAAS,SAAS;AAChC,SAAO,QAAQ,MAAM,QAAQ,SAAS,MAAM;;CAG9C,MAAM,OAAO,OAAe,QAAQ,IAAiC;EACnE,MAAM,aAAa,MAAM,aAAa;EACtC,MAAMC,UAA8B,EAAE;AAEtC,OAAK,MAAM,gBAAgB,KAAK,cAAc,QAAQ,EAAE;AAEtD,OAAI,aAAa,OAAO,aAAa,CAAC,SAAS,WAAW,EAAE;AAC1D,YAAQ,KAAK,aAAa;AAC1B;;AAOF,OAHiB,aAAa,SAAS,MAAM,MAC3C,EAAE,QAAQ,aAAa,CAAC,SAAS,WAAW,CAC7C,CAEC,SAAQ,KAAK,aAAa;AAG5B,OAAI,QAAQ,UAAU,MAAO;;AAG/B,SAAO;;;;;CAMT,QAAc;AACZ,OAAK,cAAc,OAAO;;;;;;AAO9B,SAAgB,kCAAqD;AACnE,QAAO,IAAI,2BAA2B"}
@@ -146,4 +146,5 @@ interface StreamMessageResult {
146
146
  stream: AsyncIterable<ChatStreamChunk>;
147
147
  }
148
148
  //#endregion
149
- export { ChatAttachment, ChatCodeBlock, ChatConversation, ChatMessage, ChatRole, ChatSource, ChatStreamChunk, ChatToolCall, ConversationStatus, MessageStatus, SendMessageOptions, SendMessageResult, StreamMessageResult };
149
+ export { ChatAttachment, ChatCodeBlock, ChatConversation, ChatMessage, ChatRole, ChatSource, ChatStreamChunk, ChatToolCall, ConversationStatus, MessageStatus, SendMessageOptions, SendMessageResult, StreamMessageResult };
150
+ //# sourceMappingURL=message-types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"message-types.d.ts","names":[],"sources":["../../src/core/message-types.ts"],"sourcesContent":[],"mappings":";;AAOA;AAKA;AAKA;AAaA;AAYA;AAYiB,KA/CL,QAAA,GA+Ce,MAAA,GAAA,WAAA,GAAA,QAAA;AAW3B;;;AAMa,KA3DD,aAAA,GA2DC,SAAA,GAAA,WAAA,GAAA,WAAA,GAAA,OAAA;;;;AAMC,UA5DG,cAAA,CA4DH;EACF,EAAA,EAAA,MAAA;EAkBC,IAAA,EAAA,MAAA,GAAA,OAAA,GAAA,MAAA,GAAA,MAAA;EAAM,IAAA,EAAA,MAAA;EAMP,OAAA,CAAA,EAAA,MAAA;EAKK,QAAA,CAAA,EAAA,MAAA;EAGP,IAAA,CAAA,EAAA,MAAA;EACG,IAAA,CAAA,EAAA,MAAA;;;;;AAwBI,UAzGA,aAAA,CAyGkB;EAalB,EAAA,EAAA,MAAA;EAYA,QAAA,EAAA,MAAA;EAQA,IAAA,EAAA,MAAA;;;;;;;;UA9HA,YAAA;;;QAGT;;;;;;;;UASS,UAAA;;;;;;;;;;UAWA,WAAA;;;QAGT;;UAEE;aACG;aACA;gBAGG;eACD;cACD;YACF;;;;;;;;;;aAkBC;;;;;KAMD,kBAAA;;;;UAKK,gBAAA;;;UAGP;aACG;aACA;;;;;YAWD;;aAMC;;;;;UAMI,kBAAA;;;gBAGD;;;;;;;;;UAUC,eAAA;;;aAGJ;WACF;;;;;;;;;;;;;UAQM,iBAAA;WACN;gBACK;;;;;UAMC,mBAAA;;;UAGP,cAAc"}
@@ -21,17 +21,33 @@ var BaseProvider = class {
21
21
  this.mode = this.determineMode(config);
22
22
  this.config = config;
23
23
  }
24
+ getModel() {
25
+ if (!this.cachedModel) this.cachedModel = this.createModel();
26
+ return this.cachedModel;
27
+ }
28
+ async listModels() {
29
+ if (this.name === "ollama") return this.listOllamaModels();
30
+ return getModelsForProvider(this.name);
31
+ }
32
+ async validate() {
33
+ if (this.name === "ollama") return this.validateOllama();
34
+ if (this.mode === "byok" && !this.config.apiKey) return {
35
+ valid: false,
36
+ error: `API key required for ${this.name}`
37
+ };
38
+ if (this.mode === "managed" && !this.config.proxyUrl && !this.config.organizationId) return {
39
+ valid: false,
40
+ error: "Managed mode requires proxyUrl or organizationId"
41
+ };
42
+ return { valid: true };
43
+ }
24
44
  determineMode(config) {
25
45
  if (config.provider === "ollama") return "local";
26
46
  if (config.apiKey) return "byok";
27
47
  return "managed";
28
48
  }
29
- getModel() {
30
- if (!this.cachedModel) this.cachedModel = this.createModel();
31
- return this.cachedModel;
32
- }
33
49
  createModel() {
34
- const { apiKey, baseUrl, proxyUrl, organizationId } = this.config;
50
+ const { baseUrl, proxyUrl } = this.config;
35
51
  switch (this.name) {
36
52
  case "ollama": {
37
53
  const originalBaseUrl = process.env.OLLAMA_BASE_URL;
@@ -84,10 +100,6 @@ var BaseProvider = class {
84
100
  default: throw new Error(`Unknown provider: ${this.name}`);
85
101
  }
86
102
  }
87
- async listModels() {
88
- if (this.name === "ollama") return this.listOllamaModels();
89
- return getModelsForProvider(this.name);
90
- }
91
103
  async listOllamaModels() {
92
104
  try {
93
105
  const baseUrl = this.config.baseUrl ?? "http://localhost:11434";
@@ -109,18 +121,6 @@ var BaseProvider = class {
109
121
  return getModelsForProvider("ollama");
110
122
  }
111
123
  }
112
- async validate() {
113
- if (this.name === "ollama") return this.validateOllama();
114
- if (this.mode === "byok" && !this.config.apiKey) return {
115
- valid: false,
116
- error: `API key required for ${this.name}`
117
- };
118
- if (this.mode === "managed" && !this.config.proxyUrl && !this.config.organizationId) return {
119
- valid: false,
120
- error: "Managed mode requires proxyUrl or organizationId"
121
- };
122
- return { valid: true };
123
- }
124
124
  async validateOllama() {
125
125
  try {
126
126
  const baseUrl = this.config.baseUrl ?? "http://localhost:11434";
@@ -222,4 +222,5 @@ function getAvailableProviders() {
222
222
  }
223
223
 
224
224
  //#endregion
225
- export { createProvider, createProviderFromEnv, getAvailableProviders };
225
+ export { createProvider, createProviderFromEnv, getAvailableProviders };
226
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","names":[],"sources":["../../../../../../libs/ai-providers/dist/factory.js"],"sourcesContent":["import { DEFAULT_MODELS, getModelsForProvider } from \"./models.js\";\nimport { anthropic } from \"@ai-sdk/anthropic\";\nimport { google } from \"@ai-sdk/google\";\nimport { mistral } from \"@ai-sdk/mistral\";\nimport { openai } from \"@ai-sdk/openai\";\nimport { ollama } from \"ollama-ai-provider\";\n\n//#region src/factory.ts\n/**\n* Base provider implementation\n*/\nvar BaseProvider = class {\n\tname;\n\tmodel;\n\tmode;\n\tconfig;\n\tcachedModel = null;\n\tconstructor(config) {\n\t\tthis.name = config.provider;\n\t\tthis.model = config.model ?? DEFAULT_MODELS[config.provider];\n\t\tthis.mode = this.determineMode(config);\n\t\tthis.config = config;\n\t}\n\tgetModel() {\n\t\tif (!this.cachedModel) this.cachedModel = this.createModel();\n\t\treturn this.cachedModel;\n\t}\n\tasync listModels() {\n\t\tif (this.name === \"ollama\") return this.listOllamaModels();\n\t\treturn getModelsForProvider(this.name);\n\t}\n\tasync validate() {\n\t\tif (this.name === \"ollama\") return this.validateOllama();\n\t\tif (this.mode === \"byok\" && !this.config.apiKey) return {\n\t\t\tvalid: false,\n\t\t\terror: `API key required for ${this.name}`\n\t\t};\n\t\tif (this.mode === \"managed\" && !this.config.proxyUrl && !this.config.organizationId) return {\n\t\t\tvalid: false,\n\t\t\terror: \"Managed mode requires proxyUrl or organizationId\"\n\t\t};\n\t\treturn { valid: true };\n\t}\n\tdetermineMode(config) {\n\t\tif (config.provider === \"ollama\") return \"local\";\n\t\tif (config.apiKey) return \"byok\";\n\t\treturn \"managed\";\n\t}\n\tcreateModel() {\n\t\tconst { baseUrl, proxyUrl } = this.config;\n\t\tswitch (this.name) {\n\t\t\tcase \"ollama\": {\n\t\t\t\tconst originalBaseUrl = process.env.OLLAMA_BASE_URL;\n\t\t\t\tif (baseUrl && baseUrl !== \"http://localhost:11434\") process.env.OLLAMA_BASE_URL = baseUrl;\n\t\t\t\tconst ollamaModel = ollama(this.model);\n\t\t\t\tif (originalBaseUrl !== void 0) process.env.OLLAMA_BASE_URL = originalBaseUrl;\n\t\t\t\telse if (baseUrl && baseUrl !== \"http://localhost:11434\") delete process.env.OLLAMA_BASE_URL;\n\t\t\t\treturn ollamaModel;\n\t\t\t}\n\t\t\tcase \"openai\":\n\t\t\t\tif (this.mode === \"managed\") {\n\t\t\t\t\tconst originalBaseUrl = process.env.OPENAI_BASE_URL;\n\t\t\t\t\tif (proxyUrl) process.env.OPENAI_BASE_URL = proxyUrl;\n\t\t\t\t\tconst model = openai(this.model);\n\t\t\t\t\tif (originalBaseUrl !== void 0) process.env.OPENAI_BASE_URL = originalBaseUrl;\n\t\t\t\t\telse if (proxyUrl) delete process.env.OPENAI_BASE_URL;\n\t\t\t\t\treturn model;\n\t\t\t\t}\n\t\t\t\treturn openai(this.model);\n\t\t\tcase \"anthropic\":\n\t\t\t\tif (this.mode === \"managed\") {\n\t\t\t\t\tconst originalBaseUrl = process.env.OPENAI_BASE_URL;\n\t\t\t\t\tif (proxyUrl) process.env.OPENAI_BASE_URL = proxyUrl;\n\t\t\t\t\tconst model = openai(this.model);\n\t\t\t\t\tif (originalBaseUrl !== void 0) process.env.OPENAI_BASE_URL = originalBaseUrl;\n\t\t\t\t\telse if (proxyUrl) delete process.env.OPENAI_BASE_URL;\n\t\t\t\t\treturn model;\n\t\t\t\t}\n\t\t\t\treturn anthropic(this.model);\n\t\t\tcase \"mistral\":\n\t\t\t\tif (this.mode === \"managed\") {\n\t\t\t\t\tconst originalBaseUrl = process.env.OPENAI_BASE_URL;\n\t\t\t\t\tif (proxyUrl) process.env.OPENAI_BASE_URL = proxyUrl;\n\t\t\t\t\tconst model = openai(this.model);\n\t\t\t\t\tif (originalBaseUrl !== void 0) process.env.OPENAI_BASE_URL = originalBaseUrl;\n\t\t\t\t\telse if (proxyUrl) delete process.env.OPENAI_BASE_URL;\n\t\t\t\t\treturn model;\n\t\t\t\t}\n\t\t\t\treturn mistral(this.model);\n\t\t\tcase \"gemini\":\n\t\t\t\tif (this.mode === \"managed\") {\n\t\t\t\t\tconst originalBaseUrl = process.env.OPENAI_BASE_URL;\n\t\t\t\t\tif (proxyUrl) process.env.OPENAI_BASE_URL = proxyUrl;\n\t\t\t\t\tconst model = openai(this.model);\n\t\t\t\t\tif (originalBaseUrl !== void 0) process.env.OPENAI_BASE_URL = originalBaseUrl;\n\t\t\t\t\telse if (proxyUrl) delete process.env.OPENAI_BASE_URL;\n\t\t\t\t\treturn model;\n\t\t\t\t}\n\t\t\t\treturn google(this.model);\n\t\t\tdefault: throw new Error(`Unknown provider: ${this.name}`);\n\t\t}\n\t}\n\tasync listOllamaModels() {\n\t\ttry {\n\t\t\tconst baseUrl = this.config.baseUrl ?? \"http://localhost:11434\";\n\t\t\tconst response = await fetch(`${baseUrl}/api/tags`);\n\t\t\tif (!response.ok) return getModelsForProvider(\"ollama\");\n\t\t\treturn ((await response.json()).models ?? []).map((m) => ({\n\t\t\t\tid: m.name,\n\t\t\t\tname: m.name,\n\t\t\t\tprovider: \"ollama\",\n\t\t\t\tcontextWindow: 8e3,\n\t\t\t\tcapabilities: {\n\t\t\t\t\tvision: false,\n\t\t\t\t\ttools: false,\n\t\t\t\t\treasoning: false,\n\t\t\t\t\tstreaming: true\n\t\t\t\t}\n\t\t\t}));\n\t\t} catch {\n\t\t\treturn getModelsForProvider(\"ollama\");\n\t\t}\n\t}\n\tasync validateOllama() {\n\t\ttry {\n\t\t\tconst baseUrl = this.config.baseUrl ?? \"http://localhost:11434\";\n\t\t\tconst response = await fetch(`${baseUrl}/api/tags`);\n\t\t\tif (!response.ok) return {\n\t\t\t\tvalid: false,\n\t\t\t\terror: `Ollama server returned ${response.status}`\n\t\t\t};\n\t\t\tconst models = (await response.json()).models ?? [];\n\t\t\tif (!models.some((m) => m.name === this.model)) return {\n\t\t\t\tvalid: false,\n\t\t\t\terror: `Model \"${this.model}\" not found. Available: ${models.map((m) => m.name).join(\", \")}`\n\t\t\t};\n\t\t\treturn { valid: true };\n\t\t} catch (error) {\n\t\t\treturn {\n\t\t\t\tvalid: false,\n\t\t\t\terror: `Cannot connect to Ollama at ${this.config.baseUrl ?? \"http://localhost:11434\"}: ${error instanceof Error ? error.message : String(error)}`\n\t\t\t};\n\t\t}\n\t}\n};\n/**\n* Create a provider from configuration\n*/\nfunction createProvider(config) {\n\treturn new BaseProvider(config);\n}\n/**\n* Create a provider from environment variables\n*/\nfunction createProviderFromEnv() {\n\tconst provider = process.env.CONTRACTSPEC_AI_PROVIDER ?? \"openai\";\n\tconst model = process.env.CONTRACTSPEC_AI_MODEL;\n\tlet apiKey;\n\tswitch (provider) {\n\t\tcase \"openai\":\n\t\t\tapiKey = process.env.OPENAI_API_KEY;\n\t\t\tbreak;\n\t\tcase \"anthropic\":\n\t\t\tapiKey = process.env.ANTHROPIC_API_KEY;\n\t\t\tbreak;\n\t\tcase \"mistral\":\n\t\t\tapiKey = process.env.MISTRAL_API_KEY;\n\t\t\tbreak;\n\t\tcase \"gemini\":\n\t\t\tapiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n\t\t\tbreak;\n\t\tcase \"ollama\": break;\n\t}\n\treturn createProvider({\n\t\tprovider,\n\t\tmodel,\n\t\tapiKey,\n\t\tbaseUrl: process.env.OLLAMA_BASE_URL,\n\t\tproxyUrl: process.env.CONTRACTSPEC_AI_PROXY_URL,\n\t\torganizationId: process.env.CONTRACTSPEC_ORG_ID\n\t});\n}\n/**\n* Get all available providers with their status\n*/\nfunction getAvailableProviders() {\n\tconst providers = [];\n\tproviders.push({\n\t\tprovider: \"ollama\",\n\t\tavailable: true,\n\t\tmode: \"local\"\n\t});\n\tconst openaiKey = process.env.OPENAI_API_KEY;\n\tproviders.push({\n\t\tprovider: \"openai\",\n\t\tavailable: Boolean(openaiKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),\n\t\tmode: openaiKey ? \"byok\" : \"managed\",\n\t\treason: !openaiKey ? \"Set OPENAI_API_KEY for BYOK mode\" : void 0\n\t});\n\tconst anthropicKey = process.env.ANTHROPIC_API_KEY;\n\tproviders.push({\n\t\tprovider: \"anthropic\",\n\t\tavailable: Boolean(anthropicKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),\n\t\tmode: anthropicKey ? \"byok\" : \"managed\",\n\t\treason: !anthropicKey ? \"Set ANTHROPIC_API_KEY for BYOK mode\" : void 0\n\t});\n\tconst mistralKey = process.env.MISTRAL_API_KEY;\n\tproviders.push({\n\t\tprovider: \"mistral\",\n\t\tavailable: Boolean(mistralKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),\n\t\tmode: mistralKey ? \"byok\" : \"managed\",\n\t\treason: !mistralKey ? \"Set MISTRAL_API_KEY for BYOK mode\" : void 0\n\t});\n\tconst geminiKey = process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY;\n\tproviders.push({\n\t\tprovider: \"gemini\",\n\t\tavailable: Boolean(geminiKey) || Boolean(process.env.CONTRACTSPEC_AI_PROXY_URL),\n\t\tmode: geminiKey ? \"byok\" : \"managed\",\n\t\treason: !geminiKey ? \"Set GOOGLE_API_KEY for BYOK mode\" : void 0\n\t});\n\treturn providers;\n}\n\n//#endregion\nexport { createProvider, createProviderFromEnv, getAvailableProviders };\n//# sourceMappingURL=factory.js.map"],"mappings":"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"}
@@ -296,4 +296,5 @@ function getDefaultModel(provider) {
296
296
  }
297
297
 
298
298
  //#endregion
299
- export { DEFAULT_MODELS, MODELS, getDefaultModel, getModelInfo, getModelsForProvider, getRecommendedModels };
299
+ export { DEFAULT_MODELS, MODELS, getDefaultModel, getModelInfo, getModelsForProvider, getRecommendedModels };
300
+ //# sourceMappingURL=models.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.js","names":[],"sources":["../../../../../../libs/ai-providers/dist/models.js"],"sourcesContent":["//#region src/models.ts\n/**\n* Default models per provider\n*/\nconst DEFAULT_MODELS = {\n\tollama: \"llama3.2\",\n\topenai: \"gpt-4o\",\n\tanthropic: \"claude-sonnet-4-20250514\",\n\tmistral: \"mistral-large-latest\",\n\tgemini: \"gemini-2.0-flash\"\n};\n/**\n* All recommended models with metadata\n*/\nconst MODELS = [\n\t{\n\t\tid: \"llama3.2\",\n\t\tname: \"Llama 3.2\",\n\t\tprovider: \"ollama\",\n\t\tcontextWindow: 128e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t}\n\t},\n\t{\n\t\tid: \"codellama\",\n\t\tname: \"Code Llama\",\n\t\tprovider: \"ollama\",\n\t\tcontextWindow: 16e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: false,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t}\n\t},\n\t{\n\t\tid: \"deepseek-coder\",\n\t\tname: \"DeepSeek Coder\",\n\t\tprovider: \"ollama\",\n\t\tcontextWindow: 16e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: false,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t}\n\t},\n\t{\n\t\tid: \"mistral\",\n\t\tname: \"Mistral 7B\",\n\t\tprovider: \"ollama\",\n\t\tcontextWindow: 32e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: false,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t}\n\t},\n\t{\n\t\tid: \"gpt-4o\",\n\t\tname: \"GPT-4o\",\n\t\tprovider: \"openai\",\n\t\tcontextWindow: 128e3,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 2.5,\n\t\t\toutput: 10\n\t\t}\n\t},\n\t{\n\t\tid: \"gpt-4o-mini\",\n\t\tname: \"GPT-4o Mini\",\n\t\tprovider: \"openai\",\n\t\tcontextWindow: 128e3,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .15,\n\t\t\toutput: .6\n\t\t}\n\t},\n\t{\n\t\tid: \"o1\",\n\t\tname: \"o1\",\n\t\tprovider: \"openai\",\n\t\tcontextWindow: 2e5,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: true,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 15,\n\t\t\toutput: 60\n\t\t}\n\t},\n\t{\n\t\tid: \"o1-mini\",\n\t\tname: \"o1 Mini\",\n\t\tprovider: \"openai\",\n\t\tcontextWindow: 128e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: true,\n\t\t\treasoning: true,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 3,\n\t\t\toutput: 12\n\t\t}\n\t},\n\t{\n\t\tid: \"claude-sonnet-4-20250514\",\n\t\tname: \"Claude Sonnet 4\",\n\t\tprovider: \"anthropic\",\n\t\tcontextWindow: 2e5,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: true,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 3,\n\t\t\toutput: 15\n\t\t}\n\t},\n\t{\n\t\tid: \"claude-3-5-sonnet-20241022\",\n\t\tname: \"Claude 3.5 Sonnet\",\n\t\tprovider: \"anthropic\",\n\t\tcontextWindow: 2e5,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 3,\n\t\t\toutput: 15\n\t\t}\n\t},\n\t{\n\t\tid: \"claude-3-5-haiku-20241022\",\n\t\tname: \"Claude 3.5 Haiku\",\n\t\tprovider: \"anthropic\",\n\t\tcontextWindow: 2e5,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .8,\n\t\t\toutput: 4\n\t\t}\n\t},\n\t{\n\t\tid: \"mistral-large-latest\",\n\t\tname: \"Mistral Large\",\n\t\tprovider: \"mistral\",\n\t\tcontextWindow: 128e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 2,\n\t\t\toutput: 6\n\t\t}\n\t},\n\t{\n\t\tid: \"codestral-latest\",\n\t\tname: \"Codestral\",\n\t\tprovider: \"mistral\",\n\t\tcontextWindow: 32e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .2,\n\t\t\toutput: .6\n\t\t}\n\t},\n\t{\n\t\tid: \"mistral-small-latest\",\n\t\tname: \"Mistral Small\",\n\t\tprovider: \"mistral\",\n\t\tcontextWindow: 32e3,\n\t\tcapabilities: {\n\t\t\tvision: false,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .2,\n\t\t\toutput: .6\n\t\t}\n\t},\n\t{\n\t\tid: \"gemini-2.0-flash\",\n\t\tname: \"Gemini 2.0 Flash\",\n\t\tprovider: \"gemini\",\n\t\tcontextWindow: 1e6,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: false,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .075,\n\t\t\toutput: .3\n\t\t}\n\t},\n\t{\n\t\tid: \"gemini-2.5-pro-preview-06-05\",\n\t\tname: \"Gemini 2.5 Pro\",\n\t\tprovider: \"gemini\",\n\t\tcontextWindow: 1e6,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: true,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: 1.25,\n\t\t\toutput: 10\n\t\t}\n\t},\n\t{\n\t\tid: \"gemini-2.5-flash-preview-05-20\",\n\t\tname: \"Gemini 2.5 Flash\",\n\t\tprovider: \"gemini\",\n\t\tcontextWindow: 1e6,\n\t\tcapabilities: {\n\t\t\tvision: true,\n\t\t\ttools: true,\n\t\t\treasoning: true,\n\t\t\tstreaming: true\n\t\t},\n\t\tcostPerMillion: {\n\t\t\tinput: .15,\n\t\t\toutput: .6\n\t\t}\n\t}\n];\n/**\n* Get models for a specific provider\n*/\nfunction getModelsForProvider(provider) {\n\treturn MODELS.filter((m) => m.provider === provider);\n}\n/**\n* Get model info by ID\n*/\nfunction getModelInfo(modelId) {\n\treturn MODELS.find((m) => m.id === modelId);\n}\n/**\n* Get recommended models for a provider (legacy format)\n*/\nfunction getRecommendedModels(provider) {\n\treturn getModelsForProvider(provider === \"claude\" ? \"anthropic\" : provider === \"custom\" ? \"openai\" : provider).map((m) => m.id);\n}\n/**\n* Get default model for a provider\n*/\nfunction getDefaultModel(provider) {\n\treturn DEFAULT_MODELS[provider];\n}\n\n//#endregion\nexport { DEFAULT_MODELS, MODELS, getDefaultModel, getModelInfo, getModelsForProvider, getRecommendedModels };\n//# sourceMappingURL=models.js.map"],"mappings":"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"}
@@ -57,4 +57,5 @@ async function listOllamaModels(baseUrl = "http://localhost:11434") {
57
57
  }
58
58
 
59
59
  //#endregion
60
- export { getEnvVarName, hasCredentials, isOllamaRunning, listOllamaModels, validateProvider };
60
+ export { getEnvVarName, hasCredentials, isOllamaRunning, listOllamaModels, validateProvider };
61
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.js","names":[],"sources":["../../../../../../libs/ai-providers/dist/validation.js"],"sourcesContent":["import { createProvider } from \"./factory.js\";\n\n//#region src/validation.ts\n/**\n* Validate a provider configuration\n*/\nasync function validateProvider(config) {\n\treturn createProvider(config).validate();\n}\n/**\n* Check if a provider has required credentials\n*/\nfunction hasCredentials(provider) {\n\tswitch (provider) {\n\t\tcase \"ollama\": return true;\n\t\tcase \"openai\": return Boolean(process.env.OPENAI_API_KEY);\n\t\tcase \"anthropic\": return Boolean(process.env.ANTHROPIC_API_KEY);\n\t\tcase \"mistral\": return Boolean(process.env.MISTRAL_API_KEY);\n\t\tcase \"gemini\": return Boolean(process.env.GOOGLE_API_KEY ?? process.env.GEMINI_API_KEY);\n\t\tdefault: return false;\n\t}\n}\n/**\n* Get the environment variable name for a provider's API key\n*/\nfunction getEnvVarName(provider) {\n\tswitch (provider) {\n\t\tcase \"ollama\": return null;\n\t\tcase \"openai\": return \"OPENAI_API_KEY\";\n\t\tcase \"anthropic\": return \"ANTHROPIC_API_KEY\";\n\t\tcase \"mistral\": return \"MISTRAL_API_KEY\";\n\t\tcase \"gemini\": return \"GOOGLE_API_KEY\";\n\t\tdefault: return null;\n\t}\n}\n/**\n* Check if Ollama is running\n*/\nasync function isOllamaRunning(baseUrl = \"http://localhost:11434\") {\n\ttry {\n\t\treturn (await fetch(`${baseUrl}/api/tags`)).ok;\n\t} catch {\n\t\treturn false;\n\t}\n}\n/**\n* List available Ollama models\n*/\nasync function listOllamaModels(baseUrl = \"http://localhost:11434\") {\n\ttry {\n\t\tconst response = await fetch(`${baseUrl}/api/tags`);\n\t\tif (!response.ok) return [];\n\t\treturn ((await response.json()).models ?? []).map((m) => m.name);\n\t} catch {\n\t\treturn [];\n\t}\n}\n\n//#endregion\nexport { getEnvVarName, hasCredentials, isOllamaRunning, listOllamaModels, validateProvider };\n//# sourceMappingURL=validation.js.map"],"mappings":";;;;;;AAMA,eAAe,iBAAiB,QAAQ;AACvC,QAAO,eAAe,OAAO,CAAC,UAAU;;;;;AAKzC,SAAS,eAAe,UAAU;AACjC,SAAQ,UAAR;EACC,KAAK,SAAU,QAAO;EACtB,KAAK,SAAU,QAAO,QAAQ,QAAQ,IAAI,eAAe;EACzD,KAAK,YAAa,QAAO,QAAQ,QAAQ,IAAI,kBAAkB;EAC/D,KAAK,UAAW,QAAO,QAAQ,QAAQ,IAAI,gBAAgB;EAC3D,KAAK,SAAU,QAAO,QAAQ,QAAQ,IAAI,kBAAkB,QAAQ,IAAI,eAAe;EACvF,QAAS,QAAO;;;;;;AAMlB,SAAS,cAAc,UAAU;AAChC,SAAQ,UAAR;EACC,KAAK,SAAU,QAAO;EACtB,KAAK,SAAU,QAAO;EACtB,KAAK,YAAa,QAAO;EACzB,KAAK,UAAW,QAAO;EACvB,KAAK,SAAU,QAAO;EACtB,QAAS,QAAO;;;;;;AAMlB,eAAe,gBAAgB,UAAU,0BAA0B;AAClE,KAAI;AACH,UAAQ,MAAM,MAAM,GAAG,QAAQ,WAAW,EAAE;SACrC;AACP,SAAO;;;;;;AAMT,eAAe,iBAAiB,UAAU,0BAA0B;AACnE,KAAI;EACH,MAAM,WAAW,MAAM,MAAM,GAAG,QAAQ,WAAW;AACnD,MAAI,CAAC,SAAS,GAAI,QAAO,EAAE;AAC3B,WAAS,MAAM,SAAS,MAAM,EAAE,UAAU,EAAE,EAAE,KAAK,MAAM,EAAE,KAAK;SACzD;AACP,SAAO,EAAE"}
@@ -2,4 +2,5 @@
2
2
  var __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
3
3
 
4
4
  //#endregion
5
- export { __esmMin };
5
+ export { __esmMin };
6
+ //# sourceMappingURL=rolldown_runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rolldown_runtime.js","names":[],"sources":["../../../../../../../libs/design-system/dist/_virtual/rolldown_runtime.js"],"sourcesContent":["//#region rolldown:runtime\nvar __defProp = Object.defineProperty;\nvar __getOwnPropDesc = Object.getOwnPropertyDescriptor;\nvar __getOwnPropNames = Object.getOwnPropertyNames;\nvar __hasOwnProp = Object.prototype.hasOwnProperty;\nvar __esmMin = (fn, res) => () => (fn && (res = fn(fn = 0)), res);\nvar __export = (all, symbols) => {\n\tlet target = {};\n\tfor (var name in all) {\n\t\t__defProp(target, name, {\n\t\t\tget: all[name],\n\t\t\tenumerable: true\n\t\t});\n\t}\n\tif (symbols) {\n\t\t__defProp(target, Symbol.toStringTag, { value: \"Module\" });\n\t}\n\treturn target;\n};\nvar __copyProps = (to, from, except, desc) => {\n\tif (from && typeof from === \"object\" || typeof from === \"function\") {\n\t\tfor (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {\n\t\t\tkey = keys[i];\n\t\t\tif (!__hasOwnProp.call(to, key) && key !== except) {\n\t\t\t\t__defProp(to, key, {\n\t\t\t\t\tget: ((k) => from[k]).bind(null, key),\n\t\t\t\t\tenumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t}\n\treturn to;\n};\nvar __toCommonJS = (mod) => __hasOwnProp.call(mod, \"module.exports\") ? mod[\"module.exports\"] : __copyProps(__defProp({}, \"__esModule\", { value: true }), mod);\n\n//#endregion\nexport { __esmMin, __export, __toCommonJS };"],"mappings":";AAKA,IAAI,YAAY,IAAI,eAAe,OAAO,MAAM,GAAG,KAAK,EAAE,GAAG"}
@@ -1,17 +1,17 @@
1
- import { Button } from "../../ui-kit-web/dist/ui/button.js";
1
+ import { Button as Button$1 } from "../../ui-kit-web/dist/ui/button.js";
2
2
  import "react";
3
3
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
4
4
  import { Loader2 } from "lucide-react";
5
5
 
6
6
  //#region ../../libs/design-system/dist/components/atoms/Button.js
7
- function Button$1({ children, loading, spinnerPlacement = "start", onPress, onPressIn, onPressOut, onLongPress, onTouchStart, onTouchEnd, onTouchCancel, onMouseDown, onMouseUp, onClick, className, disabled, ...rest }) {
7
+ function Button({ children, loading, spinnerPlacement = "start", onPress, onPressIn, onPressOut, onLongPress, onTouchStart, onTouchEnd, onTouchCancel, onMouseDown, onMouseUp, onClick, className, disabled, ...rest }) {
8
8
  const isDisabled = Boolean(disabled || loading);
9
9
  const content = !rest.asChild ? /* @__PURE__ */ jsxs(Fragment, { children: [
10
10
  loading && spinnerPlacement === "start" ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : null,
11
11
  children,
12
12
  loading && spinnerPlacement === "end" ? /* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : null
13
13
  ] }) : children;
14
- return /* @__PURE__ */ jsx(Button, {
14
+ return /* @__PURE__ */ jsx(Button$1, {
15
15
  ...rest,
16
16
  className,
17
17
  disabled: isDisabled,
@@ -30,4 +30,5 @@ function Button$1({ children, loading, spinnerPlacement = "start", onPress, onPr
30
30
  }
31
31
 
32
32
  //#endregion
33
- export { Button$1 };
33
+ export { Button };
34
+ //# sourceMappingURL=Button.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Button.js","names":[],"sources":["../../../../../../../../libs/design-system/dist/components/atoms/Button.js"],"sourcesContent":["import { Button as Button$1 } from \"../../ui-kit-web/dist/ui/button.js\";\nimport \"react\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nimport { Loader2 } from \"lucide-react\";\n\n//#region src/components/atoms/Button.tsx\nfunction Button({ children, loading, spinnerPlacement = \"start\", onPress, onPressIn, onPressOut, onLongPress, onTouchStart, onTouchEnd, onTouchCancel, onMouseDown, onMouseUp, onClick, className, disabled, ...rest }) {\n\tconst isDisabled = Boolean(disabled || loading);\n\tconst content = !rest.asChild ? /* @__PURE__ */ jsxs(Fragment, { children: [\n\t\tloading && spinnerPlacement === \"start\" ? /* @__PURE__ */ jsx(Loader2, { className: \"h-4 w-4 animate-spin\" }) : null,\n\t\tchildren,\n\t\tloading && spinnerPlacement === \"end\" ? /* @__PURE__ */ jsx(Loader2, { className: \"h-4 w-4 animate-spin\" }) : null\n\t] }) : children;\n\treturn /* @__PURE__ */ jsx(Button$1, {\n\t\t...rest,\n\t\tclassName,\n\t\tdisabled: isDisabled,\n\t\t\"aria-busy\": loading ? true : void 0,\n\t\t\"aria-disabled\": isDisabled ? true : void 0,\n\t\tonPress: onPress || onClick,\n\t\tonClick: onPress || onClick,\n\t\tonMouseDown: onMouseDown || onPressIn,\n\t\tonMouseUp: onMouseUp || onPressOut,\n\t\tonTouchStart,\n\t\tonTouchEnd: onTouchEnd || onPressOut,\n\t\tonTouchCancel: onTouchCancel || onPressOut,\n\t\ttype: rest?.type ?? \"button\",\n\t\tchildren: content\n\t});\n}\n\n//#endregion\nexport { Button };\n//# sourceMappingURL=Button.js.map"],"mappings":";;;;;;AAMA,SAAS,OAAO,EAAE,UAAU,SAAS,mBAAmB,SAAS,SAAS,WAAW,YAAY,aAAa,cAAc,YAAY,eAAe,aAAa,WAAW,SAAS,WAAW,UAAU,GAAG,QAAQ;CACvN,MAAM,aAAa,QAAQ,YAAY,QAAQ;CAC/C,MAAM,UAAU,CAAC,KAAK,UAA0B,qBAAK,UAAU,EAAE,UAAU;EAC1E,WAAW,qBAAqB,UAA0B,oBAAI,SAAS,EAAE,WAAW,wBAAwB,CAAC,GAAG;EAChH;EACA,WAAW,qBAAqB,QAAwB,oBAAI,SAAS,EAAE,WAAW,wBAAwB,CAAC,GAAG;EAC9G,EAAE,CAAC,GAAG;AACP,QAAuB,oBAAI,UAAU;EACpC,GAAG;EACH;EACA,UAAU;EACV,aAAa,UAAU,OAAO,KAAK;EACnC,iBAAiB,aAAa,OAAO,KAAK;EAC1C,SAAS,WAAW;EACpB,SAAS,WAAW;EACpB,aAAa,eAAe;EAC5B,WAAW,aAAa;EACxB;EACA,YAAY,cAAc;EAC1B,eAAe,iBAAiB;EAChC,MAAM,MAAM,QAAQ;EACpB,UAAU;EACV,CAAC"}
@@ -1,10 +1,10 @@
1
1
  import { mapKeyboardToWeb } from "../../lib/keyboard.js";
2
- import { Textarea } from "../../ui-kit-web/dist/ui/textarea.js";
2
+ import { Textarea as Textarea$1 } from "../../ui-kit-web/dist/ui/textarea.js";
3
3
  import * as React$1 from "react";
4
4
  import { jsx } from "react/jsx-runtime";
5
5
 
6
6
  //#region ../../libs/design-system/dist/components/atoms/Textarea.js
7
- function Textarea$1({ value, defaultValue, onChange, onSubmit, onFocus, onBlur, placeholder, disabled, readOnly, maxLength, name, className, rows, keyboard, ...rest }) {
7
+ function Textarea({ value, defaultValue, onChange, onSubmit, onFocus, onBlur, placeholder, disabled, readOnly, maxLength, name, className, rows, keyboard, ...rest }) {
8
8
  const webKeyboard = mapKeyboardToWeb(keyboard);
9
9
  const handleChange = React$1.useCallback((e) => onChange?.(e), [onChange]);
10
10
  const handleKeyDown = React$1.useCallback((e) => {
@@ -12,7 +12,7 @@ function Textarea$1({ value, defaultValue, onChange, onSubmit, onFocus, onBlur,
12
12
  if (e.metaKey || e.ctrlKey) onSubmit?.(e);
13
13
  }
14
14
  }, [onSubmit, webKeyboard.type]);
15
- return /* @__PURE__ */ jsx(Textarea, {
15
+ return /* @__PURE__ */ jsx(Textarea$1, {
16
16
  ...rest,
17
17
  className,
18
18
  value,
@@ -32,4 +32,5 @@ function Textarea$1({ value, defaultValue, onChange, onSubmit, onFocus, onBlur,
32
32
  }
33
33
 
34
34
  //#endregion
35
- export { Textarea$1 };
35
+ export { Textarea };
36
+ //# sourceMappingURL=Textarea.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Textarea.js","names":[],"sources":["../../../../../../../../libs/design-system/dist/components/atoms/Textarea.js"],"sourcesContent":["import { mapKeyboardToWeb } from \"../../lib/keyboard.js\";\nimport { Textarea as Textarea$1 } from \"../../ui-kit-web/dist/ui/textarea.js\";\nimport * as React$1 from \"react\";\nimport { jsx } from \"react/jsx-runtime\";\n\n//#region src/components/atoms/Textarea.tsx\nfunction Textarea({ value, defaultValue, onChange, onSubmit, onFocus, onBlur, placeholder, disabled, readOnly, maxLength, name, className, rows, keyboard, ...rest }) {\n\tconst webKeyboard = mapKeyboardToWeb(keyboard);\n\tconst handleChange = React$1.useCallback((e) => onChange?.(e), [onChange]);\n\tconst handleKeyDown = React$1.useCallback((e) => {\n\t\tif (e.key === \"Enter\" && webKeyboard.type !== \"search\") {\n\t\t\tif (e.metaKey || e.ctrlKey) onSubmit?.(e);\n\t\t}\n\t}, [onSubmit, webKeyboard.type]);\n\treturn /* @__PURE__ */ jsx(Textarea$1, {\n\t\t...rest,\n\t\tclassName,\n\t\tvalue,\n\t\tdefaultValue,\n\t\tonChange: handleChange,\n\t\tonKeyDown: handleKeyDown,\n\t\tonFocus,\n\t\tonBlur,\n\t\tplaceholder,\n\t\tdisabled,\n\t\treadOnly,\n\t\tmaxLength,\n\t\tname,\n\t\trows,\n\t\t...webKeyboard\n\t});\n}\n\n//#endregion\nexport { Textarea };\n//# sourceMappingURL=Textarea.js.map"],"mappings":";;;;;;AAMA,SAAS,SAAS,EAAE,OAAO,cAAc,UAAU,UAAU,SAAS,QAAQ,aAAa,UAAU,UAAU,WAAW,MAAM,WAAW,MAAM,UAAU,GAAG,QAAQ;CACrK,MAAM,cAAc,iBAAiB,SAAS;CAC9C,MAAM,eAAe,QAAQ,aAAa,MAAM,WAAW,EAAE,EAAE,CAAC,SAAS,CAAC;CAC1E,MAAM,gBAAgB,QAAQ,aAAa,MAAM;AAChD,MAAI,EAAE,QAAQ,WAAW,YAAY,SAAS,UAC7C;OAAI,EAAE,WAAW,EAAE,QAAS,YAAW,EAAE;;IAExC,CAAC,UAAU,YAAY,KAAK,CAAC;AAChC,QAAuB,oBAAI,YAAY;EACtC,GAAG;EACH;EACA;EACA;EACA,UAAU;EACV,WAAW;EACX;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,GAAG;EACH,CAAC"}
@@ -190,4 +190,5 @@ function mapKeyboardToWeb(opts) {
190
190
  }
191
191
 
192
192
  //#endregion
193
- export { mapKeyboardToWeb };
193
+ export { mapKeyboardToWeb };
194
+ //# sourceMappingURL=keyboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keyboard.js","names":[],"sources":["../../../../../../../libs/design-system/dist/lib/keyboard.js"],"sourcesContent":["//#region src/lib/keyboard.ts\nfunction deriveKindFromAutoComplete(ac) {\n\tif (!ac) return void 0;\n\tswitch (ac) {\n\t\tcase \"email\": return \"email\";\n\t\tcase \"url\": return \"url\";\n\t\tcase \"username\": return \"username\";\n\t\tcase \"new-password\": return \"new-password\";\n\t\tcase \"current-password\": return \"password\";\n\t\tcase \"one-time-code\": return \"otp\";\n\t\tcase \"tel\":\n\t\tcase \"tel-country-code\":\n\t\tcase \"tel-national\":\n\t\tcase \"tel-area-code\":\n\t\tcase \"tel-local\":\n\t\tcase \"tel-local-prefix\":\n\t\tcase \"tel-local-suffix\":\n\t\tcase \"tel-extension\": return \"tel\";\n\t\tcase \"postal-code\":\n\t\tcase \"cc-number\":\n\t\tcase \"cc-csc\":\n\t\tcase \"bday-day\":\n\t\tcase \"bday-month\":\n\t\tcase \"bday-year\": return \"int\";\n\t\tcase \"cc-exp\":\n\t\tcase \"cc-exp-month\":\n\t\tcase \"cc-exp-year\": return \"numbers-and-punctuation\";\n\t\tcase \"bday\": return \"date\";\n\t\tdefault: return \"text\";\n\t}\n}\nfunction applyAutoCompleteDefaultsWeb(res, ac) {\n\tif (!ac) return;\n\tif ([\n\t\t\"name\",\n\t\t\"given-name\",\n\t\t\"additional-name\",\n\t\t\"family-name\",\n\t\t\"honorific-prefix\",\n\t\t\"honorific-suffix\",\n\t\t\"nickname\",\n\t\t\"organization\",\n\t\t\"organization-title\",\n\t\t\"cc-name\",\n\t\t\"cc-given-name\",\n\t\t\"cc-additional-name\",\n\t\t\"cc-family-name\"\n\t].includes(ac)) res.autoCapitalize = \"words\";\n\tif ([\n\t\t\"username\",\n\t\t\"new-password\",\n\t\t\"current-password\",\n\t\t\"one-time-code\",\n\t\t\"email\",\n\t\t\"url\"\n\t].includes(ac)) res.autoCapitalize = \"none\";\n}\nfunction mapKeyboardToWeb(opts) {\n\tconst kind = opts?.kind ?? deriveKindFromAutoComplete(opts?.autoComplete) ?? \"text\";\n\tconst res = {};\n\tswitch (kind) {\n\t\tcase \"password\":\n\t\t\tres.type = \"password\";\n\t\t\tres.autoCapitalize = \"none\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"current-password\";\n\t\t\tif (opts?.autoCorrect != null) res.autoCorrect = opts.autoCorrect;\n\t\t\tbreak;\n\t\tcase \"new-password\":\n\t\t\tres.type = \"password\";\n\t\t\tres.autoCapitalize = \"none\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"new-password\";\n\t\t\tif (opts?.autoCorrect != null) res.autoCorrect = opts.autoCorrect;\n\t\t\tbreak;\n\t\tcase \"username\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoCapitalize = \"none\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"username\";\n\t\t\tbreak;\n\t\tcase \"email\":\n\t\t\tres.type = \"email\";\n\t\t\tres.inputMode = \"email\";\n\t\t\tres.autoCapitalize = \"none\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"email\";\n\t\t\tbreak;\n\t\tcase \"url\":\n\t\t\tres.type = \"url\";\n\t\t\tres.inputMode = \"url\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"url\";\n\t\t\tbreak;\n\t\tcase \"search\":\n\t\t\tres.type = \"search\";\n\t\t\tres.inputMode = \"search\";\n\t\t\tres.enterKeyHint = opts?.enterKeyHint ?? \"search\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"off\";\n\t\t\tbreak;\n\t\tcase \"phone\":\n\t\tcase \"tel\":\n\t\t\tres.type = \"tel\";\n\t\t\tres.inputMode = \"tel\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"tel\";\n\t\t\tbreak;\n\t\tcase \"number\":\n\t\tcase \"int\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.pattern = \"[0-9]*\";\n\t\t\tbreak;\n\t\tcase \"decimal\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"decimal\";\n\t\t\tres.step = \"any\";\n\t\t\tbreak;\n\t\tcase \"numbers-and-punctuation\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"text\";\n\t\t\tres.pattern = \"[0-9.,-]*\";\n\t\t\tbreak;\n\t\tcase \"otp\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"one-time-code\";\n\t\t\tres.autoCapitalize = \"none\";\n\t\t\tbreak;\n\t\tcase \"name\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"name\";\n\t\t\tres.autoCapitalize = opts?.autoCapitalize ?? \"words\";\n\t\t\tbreak;\n\t\tcase \"given-name\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"given-name\";\n\t\t\tres.autoCapitalize = opts?.autoCapitalize ?? \"words\";\n\t\t\tbreak;\n\t\tcase \"family-name\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"family-name\";\n\t\t\tres.autoCapitalize = opts?.autoCapitalize ?? \"words\";\n\t\t\tbreak;\n\t\tcase \"address-line1\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"address-line1\";\n\t\t\tbreak;\n\t\tcase \"address-line2\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"address-line2\";\n\t\t\tbreak;\n\t\tcase \"postal-code\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.pattern = \"[0-9]*\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"postal-code\";\n\t\t\tbreak;\n\t\tcase \"cc-number\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.pattern = \"[0-9]*\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"cc-number\";\n\t\t\tbreak;\n\t\tcase \"cc-exp\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.pattern = \"[0-9/]*\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"cc-exp\";\n\t\t\tbreak;\n\t\tcase \"cc-csc\":\n\t\t\tres.type = \"text\";\n\t\t\tres.inputMode = \"numeric\";\n\t\t\tres.pattern = \"[0-9]*\";\n\t\t\tres.autoComplete = opts?.autoComplete ?? \"cc-csc\";\n\t\t\tbreak;\n\t\tcase \"off\":\n\t\t\tres.type = \"text\";\n\t\t\tres.autoComplete = \"off\";\n\t\t\tbreak;\n\t\tcase \"date\":\n\t\t\tres.type = \"date\";\n\t\t\tres.inputMode = \"date\";\n\t\t\tres.pattern = \"[0-9./-]*\";\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tres.type = \"text\";\n\t\t\tbreak;\n\t}\n\tif (opts?.autoCapitalize) res.autoCapitalize = opts.autoCapitalize;\n\tif (opts?.autoComplete) res.autoComplete = opts.autoComplete;\n\tif (opts?.autoCorrect != null) res.autoCorrect = opts.autoCorrect;\n\tif (opts?.enterKeyHint) res.enterKeyHint = opts.enterKeyHint;\n\tapplyAutoCompleteDefaultsWeb(res, opts?.autoComplete);\n\treturn res;\n}\n\n//#endregion\nexport { mapKeyboardToWeb };\n//# sourceMappingURL=keyboard.js.map"],"mappings":"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"}
@@ -52,4 +52,5 @@ const Button = React$1.forwardRef(({ className, variant, size, asChild = false,
52
52
  Button.displayName = "Button";
53
53
 
54
54
  //#endregion
55
- export { Button };
55
+ export { Button };
56
+ //# sourceMappingURL=button.js.map