@eclipse-lyra/extension-ai-system 0.0.0 → 0.7.6
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.
|
@@ -2353,7 +2353,7 @@ contributionRegistry.registerContribution(CID_AGENTS, {
|
|
|
2353
2353
|
contributionRegistry.registerContribution(TOOLBAR_BOTTOM, {
|
|
2354
2354
|
target: TOOLBAR_BOTTOM,
|
|
2355
2355
|
label: "Token Usage",
|
|
2356
|
-
|
|
2356
|
+
component: "<lyra-token-usage></lyra-token-usage>"
|
|
2357
2357
|
});
|
|
2358
2358
|
editorRegistry.registerEditorInputHandler({
|
|
2359
2359
|
editorId: "system.ai-config-editor",
|
|
@@ -2361,7 +2361,7 @@ editorRegistry.registerEditorInputHandler({
|
|
|
2361
2361
|
ranking: 1e3,
|
|
2362
2362
|
canHandle: (input) => input.key === ".system.ai-config",
|
|
2363
2363
|
handle: async (input) => {
|
|
2364
|
-
input.
|
|
2364
|
+
input.component = () => html`<lyra-ai-config-editor .input="${input}"></lyra-ai-config-editor>`;
|
|
2365
2365
|
return input;
|
|
2366
2366
|
}
|
|
2367
2367
|
});
|
|
@@ -2391,4 +2391,4 @@ registerAll({
|
|
|
2391
2391
|
}
|
|
2392
2392
|
});
|
|
2393
2393
|
rootContext.put("aiService", aiService);
|
|
2394
|
-
//# sourceMappingURL=ai-system-extension-
|
|
2394
|
+
//# sourceMappingURL=ai-system-extension-Rr1JZnwv.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-system-extension-CPLV13Lk.js","sources":["../src/general-assistant-prompt.txt?raw","../src/chat-provider-contributions.ts","../src/prompt-enhancer-contributions.ts","../src/view/session-manager.ts","../src/view/stream-manager.ts","../src/view/provider-manager.ts","../src/view/agent-group-manager.ts","../src/view/components/ai-chat-message.ts","../src/view/components/ai-chat-input.ts","../src/view/components/ai-agent-response-group.ts","../src/view/components/ai-tool-approval.ts","../src/view/components/ai-empty-state.ts","../src/view/task-progress-panel.ts","../src/view/workspace-panel.ts","../src/view/aiview.ts","../src/view/token-usage.ts","../src/view/components/ai-config-editor.ts","../src/ai-system-extension.ts"],"sourcesContent":["export default \"You are an assistant in a web application with workspace, editors, and AI chat.\\n\\n**Tools:**\\nCommands are exposed as AI-callable tools. Tools are context-aware - available commands depend on active editor, selected files, and workspace state.\\n\\n**Tool Usage Rules:**\\n1. If tools are available and match the request, use them - don't describe manual steps\\n2. Read tool descriptions/parameters to select the correct tool\\n3. Call tools in sequence for multi-step tasks\\n4. After successful tool execution, provide a final response - don't loop or call more tools unless explicitly requested\\n5. If no tools are available, explain what context is needed\\n\\nKeep responses concise. Use tools when available rather than discussing alternatives.\\n\\n\"","import { contributionRegistry } from '@eclipse-lyra/core';\nimport { CID_CHAT_PROVIDERS } from './core/constants';\nimport type { ChatProviderContribution } from './core/interfaces';\n\nconst providers: Array<{ label: string; name: string; model: string; chatApiEndpoint: string; apiKey: string; parameters?: Record<string, any> }> = [\n { label: 'Ollama (Local)', name: 'ollama', model: 'gemma3:12b', chatApiEndpoint: 'https://<your-server>/v1/chat/completions', apiKey: '' },\n { label: 'OpenWebUI (Self Hosted)', name: 'openwebui', model: 'gemma3:12b', chatApiEndpoint: 'https://<your-server>/api/v1/chat/completion', apiKey: '' },\n { label: 'OpenAI', name: 'openai', model: 'gpt-4.1', chatApiEndpoint: 'https://api.openai.com/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'Groq', name: 'groq', model: 'llama-3.1-8b-instant', chatApiEndpoint: 'https://api.groq.com/openai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'Cerebras', name: 'cerebras', model: 'llama3.1-8b', chatApiEndpoint: 'https://api.cerebras.ai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'WebLLM', name: 'webllm', model: 'gemma-2-9b-it-q4f16_1-MLC', chatApiEndpoint: '', apiKey: '', parameters: { context_window_size: 4096 } },\n { label: 'Mistral', name: 'mistral', model: 'mistral-large-latest', chatApiEndpoint: 'https://api.mistral.ai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'LiteLLM', name: 'litellm', model: 'gpt-3.5-turbo', chatApiEndpoint: 'https://<your-server>/v1/chat/completions', apiKey: '<your api key>' },\n];\n\nfor (const { label, ...provider } of providers) {\n contributionRegistry.registerContribution<ChatProviderContribution>(CID_CHAT_PROVIDERS, {\n target: CID_CHAT_PROVIDERS,\n label,\n provider\n });\n}\n","import { contributionRegistry, workspaceService, editorRegistry } from '@eclipse-lyra/core';\nimport type { ExecutionContext } from '@eclipse-lyra/core';\nimport { CID_PROMPT_ENHANCERS } from './core/constants';\nimport type { PromptEnhancer, PromptEnhancerContribution } from './core/interfaces';\n\nconst appStateEnhancer: PromptEnhancer = {\n priority: 20,\n enhance: async (prompt: string, _context: ExecutionContext) => {\n try {\n const workspace = await workspaceService.getWorkspace();\n const activeEditor = editorRegistry.getEditorArea()?.getActiveEditor();\n const appState = {\n workspace: workspace?.getName() || null,\n activeEditor: activeEditor ? {\n title: (activeEditor as any).input?.title || null,\n editorId: (activeEditor as any).input?.editorId || null\n } : null\n };\n return `${prompt}\\n\\n***App's state:***\\n${JSON.stringify(appState, null, 2)}`;\n } catch {\n return prompt;\n }\n }\n};\n\ncontributionRegistry.registerContribution(CID_PROMPT_ENHANCERS, {\n label: 'App State Enhancer',\n enhancer: appStateEnhancer\n} as PromptEnhancerContribution);\n","import { appSettings } from \"@eclipse-lyra/core\";\nimport type { ChatMessage } from \"../core/types\";\n\nexport interface Session {\n id: string;\n history: ChatMessage[];\n title: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class SessionManager {\n private activeSession: Session | null = null;\n private pastSessions: Session[] = [];\n\n async load(): Promise<void> {\n const saved = await appSettings.get('aiChatSessions') as any;\n if (!saved) return;\n\n if (saved.active && Array.isArray(saved.history)) {\n this.activeSession = saved.active;\n } else if (saved.activeSessionId && Array.isArray(saved.sessions)) {\n this.activeSession = saved.sessions.find((s: Session) => s.id === saved.activeSessionId) || null;\n this.pastSessions = saved.sessions.filter((s: Session) => s.id !== saved.activeSessionId);\n } else if (Array.isArray(saved.all)) {\n const [first, ...rest] = (saved.all as Session[]).sort((a, b) => b.updatedAt - a.updatedAt);\n this.activeSession = first || null;\n this.pastSessions = rest;\n }\n }\n\n async persist(): Promise<void> {\n const all: Session[] = [];\n if (this.activeSession) all.push(this.activeSession);\n all.push(...this.pastSessions);\n\n await appSettings.set('aiChatSessions', {\n all,\n activeSessionId: this.activeSession?.id || null\n });\n }\n\n createSession(): Session {\n const session: Session = {\n id: `session-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n history: [],\n title: 'New Chat',\n createdAt: Date.now(),\n updatedAt: Date.now()\n };\n if (this.activeSession) {\n this.pastSessions.unshift(this.activeSession);\n }\n this.activeSession = session;\n this.persist();\n return session;\n }\n\n getActiveSession(): Session | null {\n return this.activeSession;\n }\n\n getActiveSessionId(): string {\n return this.activeSession?.id || '';\n }\n\n switchToSession(sessionId: string): boolean {\n if (this.activeSession?.id === sessionId) return true;\n\n const idx = this.pastSessions.findIndex(s => s.id === sessionId);\n if (idx === -1) return false;\n\n const [target] = this.pastSessions.splice(idx, 1);\n if (!target) return false;\n\n if (this.activeSession) this.pastSessions.unshift(this.activeSession);\n this.activeSession = target;\n\n this.persist();\n return true;\n }\n\n getPastSessions(): Session[] {\n return this.pastSessions;\n }\n\n deletePastSession(sessionId: string): boolean {\n const idx = this.pastSessions.findIndex(s => s.id === sessionId);\n if (idx === -1) return false;\n this.pastSessions.splice(idx, 1);\n this.persist();\n return true;\n }\n\n addMessage(message: ChatMessage): void {\n if (!this.activeSession) return;\n this.activeSession.history.push(message);\n this.activeSession.updatedAt = Date.now();\n this.persist();\n }\n\n setTitle(title: string): void {\n if (!this.activeSession) return;\n this.activeSession.title = title;\n this.persist();\n }\n\n generateTitle(prompt: string): string {\n const trimmed = prompt.trim();\n if (!trimmed) return 'New Chat';\n return trimmed.length <= 30 ? trimmed : trimmed.substring(0, 30).trim() + '...';\n }\n\n deleteActiveAndSwitchToFirst(): void {\n if (!this.activeSession) return;\n this.activeSession = this.pastSessions.shift() || null;\n if (!this.activeSession) {\n this.createSession();\n }\n this.persist();\n }\n}\n","import type { ChatMessage } from \"../core/types\";\n\nexport interface StreamingMessage {\n message: ChatMessage;\n isStreaming: boolean;\n}\n\nexport class StreamManager {\n private streamingMessages = new Map<number, StreamingMessage>();\n private currentIndex = -1;\n private rafHandle?: number;\n private pendingUpdate = false;\n private onUpdate?: () => void;\n\n constructor(onUpdate?: () => void) {\n this.onUpdate = onUpdate;\n }\n\n createStreamingMessage(role: string): number {\n const index = ++this.currentIndex;\n this.streamingMessages.set(index, { message: { role, content: '' }, isStreaming: true });\n return index;\n }\n\n updateStreamingMessage(index: number, token: string): void {\n const msg = this.streamingMessages.get(index);\n if (!msg) return;\n msg.message.content += token;\n this.scheduleUpdate();\n }\n\n completeStreamingMessage(index: number, message: ChatMessage): void {\n const msg = this.streamingMessages.get(index);\n if (!msg) return;\n msg.message = message;\n msg.isStreaming = false;\n }\n\n removeStreamingMessage(index: number): void {\n this.streamingMessages.delete(index);\n }\n\n findStreamingMessage(role: string): ChatMessage | undefined {\n return Array.from(this.streamingMessages.values()).find(m => m.message.role === role)?.message;\n }\n\n getAllStreamingMessages(): StreamingMessage[] {\n return Array.from(this.streamingMessages.values());\n }\n\n scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.rafHandle = requestAnimationFrame(() => {\n this.pendingUpdate = false;\n this.onUpdate?.();\n });\n }\n\n cancelUpdates(): void {\n if (this.rafHandle !== undefined) {\n cancelAnimationFrame(this.rafHandle);\n this.rafHandle = undefined;\n this.pendingUpdate = false;\n }\n }\n\n reset(): void {\n this.streamingMessages.clear();\n this.cancelUpdates();\n this.currentIndex = -1;\n }\n}\n","import { appSettings } from \"@eclipse-lyra/core\";\nimport type { ChatProvider } from \"../core/types\";\nimport type { AIService } from \"../service/ai-service\";\nimport { KEY_AI_CONFIG } from \"../core/constants\";\nimport { ProviderFactory } from \"../providers/provider-factory\";\n\nexport interface AIViewSettings {\n requireToolApproval?: boolean;\n toolApprovalAllowlist?: string[];\n}\n\nexport interface ModelInfo {\n id: string;\n name?: string;\n}\n\nconst VIEW_SETTINGS_KEY = 'aiViewChat';\n\nexport class ProviderManager {\n private providers: ChatProvider[] = [];\n private selectedProvider?: ChatProvider;\n private availableModels: ModelInfo[] = [];\n private loadingModels = false;\n\n private providerFactory = new ProviderFactory();\n\n constructor(private aiService: AIService) {}\n\n async initialize(): Promise<void> {\n this.providers = await this.aiService.getProviders() || [];\n const defaultProvider = await this.aiService.getDefaultProvider();\n if (defaultProvider) {\n this.selectedProvider = defaultProvider;\n }\n }\n\n getProviders(): ChatProvider[] { return this.providers; }\n getSelectedProvider(): ChatProvider | undefined { return this.selectedProvider; }\n setSelectedProvider(provider: ChatProvider): void { this.selectedProvider = provider; }\n getAvailableModels(): ModelInfo[] { return this.availableModels; }\n isLoadingModels(): boolean { return this.loadingModels; }\n\n async saveSettings(providerName: string, model: string, apiKey?: string, requireToolApproval?: boolean, toolApprovalAllowlist?: string[]): Promise<void> {\n const current: AIViewSettings = await appSettings.get(VIEW_SETTINGS_KEY) || {};\n const settings: AIViewSettings = { ...current };\n if (requireToolApproval !== undefined) settings.requireToolApproval = requireToolApproval;\n if (toolApprovalAllowlist !== undefined) settings.toolApprovalAllowlist = toolApprovalAllowlist;\n await appSettings.set(VIEW_SETTINGS_KEY, settings);\n\n const provider = this.providers.find(p => p.name === providerName);\n if (provider) {\n const updated = { ...provider, model, ...(apiKey !== undefined && { apiKey }) };\n this.selectedProvider = updated;\n await this.updateProviderInAIConfig(providerName, { model, ...(apiKey !== undefined && { apiKey }) });\n await this.aiService.setDefaultProvider(providerName);\n }\n }\n\n private async updateProviderInAIConfig(providerName: string, updates: { model?: string; apiKey?: string }): Promise<void> {\n const aiConfig = await appSettings.get(KEY_AI_CONFIG) || {};\n if (!aiConfig.providers || !Array.isArray(aiConfig.providers)) return;\n const idx = aiConfig.providers.findIndex((p: any) => p.name === providerName);\n if (idx >= 0) {\n aiConfig.providers[idx] = { ...aiConfig.providers[idx], ...updates };\n await appSettings.set(KEY_AI_CONFIG, aiConfig);\n }\n }\n\n async loadToolApprovalAllowlist(): Promise<string[]> {\n const settings: AIViewSettings = await appSettings.get(VIEW_SETTINGS_KEY) || {};\n return settings.toolApprovalAllowlist || [];\n }\n\n async fetchModels(providerName: string): Promise<void> {\n const provider = this.providers.find(p => p.name === providerName);\n if (!provider) return;\n\n this.loadingModels = true;\n this.availableModels = [];\n\n try {\n const baseProvider = this.providerFactory.getProvider(provider);\n this.availableModels = await baseProvider.getAvailableModels?.(provider) ?? [];\n } finally {\n this.loadingModels = false;\n }\n }\n}\n","import type { ChatMessage } from \"../core/types\";\n\nexport interface AgentResponseInfo {\n role: string;\n label: string;\n icon: string;\n status: 'streaming' | 'completed' | 'error';\n message?: ChatMessage;\n messageIndex?: number;\n}\n\nexport interface AgentResponseGroup {\n id: string;\n sessionId: string;\n userMessageIndex: number;\n userMessage: ChatMessage;\n timestamp: Date;\n agents: Map<string, AgentResponseInfo>;\n messageIndices: Map<string, number>;\n}\n\nexport class AgentGroupManager {\n private groups = new Map<string, AgentResponseGroup>();\n private currentGroupId?: string;\n\n createGroup(\n sessionId: string,\n userMessageIndex: number,\n userMessage: ChatMessage,\n roles: string[],\n getAgentMetadata: (role: string) => { label: string; icon: string }\n ): string {\n const groupId = `group-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n this.currentGroupId = groupId;\n\n const group: AgentResponseGroup = {\n id: groupId,\n sessionId,\n userMessageIndex,\n userMessage,\n timestamp: new Date(),\n agents: new Map(),\n messageIndices: new Map()\n };\n\n roles.forEach(role => {\n const { label, icon } = getAgentMetadata(role);\n group.agents.set(role, { role, label, icon, status: 'streaming' });\n });\n\n this.groups.set(groupId, group);\n return groupId;\n }\n\n getGroup(groupId: string): AgentResponseGroup | undefined {\n return this.groups.get(groupId);\n }\n\n updateAgentStatus(groupId: string, role: string, status: AgentResponseInfo['status'], message?: ChatMessage, messageIndex?: number): void {\n const group = this.groups.get(groupId);\n if (!group) return;\n const agentInfo = group.agents.get(role);\n if (!agentInfo) return;\n agentInfo.status = status;\n if (message) agentInfo.message = message;\n if (messageIndex !== undefined) {\n agentInfo.messageIndex = messageIndex;\n group.messageIndices.set(role, messageIndex);\n }\n }\n\n getGroupsForSession(sessionId: string): AgentResponseGroup[] {\n return Array.from(this.groups.values()).filter(g => g.sessionId === sessionId);\n }\n\n findGroupForUserMessage(sessionId: string, userMessageIndex: number, userMessage: ChatMessage): AgentResponseGroup | undefined {\n return Array.from(this.groups.values()).find(\n g => g.sessionId === sessionId && g.userMessageIndex === userMessageIndex && g.userMessage === userMessage\n );\n }\n\n findGroupForMessage(sessionId: string, messageRole: string, messageIndex: number): AgentResponseGroup | undefined {\n return Array.from(this.groups.values()).find(\n g => g.sessionId === sessionId && g.messageIndices.get(messageRole) === messageIndex\n );\n }\n\n getCurrentGroupId(): string | undefined { return this.currentGroupId; }\n setCurrentGroupId(groupId: string | undefined): void { this.currentGroupId = groupId; }\n clearCurrentGroup(): void { this.currentGroupId = undefined; }\n getAllGroups(): AgentResponseGroup[] { return Array.from(this.groups.values()); }\n\n clearAll(): void {\n this.groups.clear();\n this.currentGroupId = undefined;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { when } from 'lit/directives/when.js';\nimport { marked } from 'marked';\nimport type { ChatMessage } from '../../core/types';\n\n@customElement('lyra-ai-chat-message')\nexport class AIChatMessage extends LitElement {\n @property({ type: Object, attribute: false })\n public message?: ChatMessage;\n\n @property({ type: Boolean })\n public isStreaming = false;\n\n @property({ type: Boolean })\n public showHeader = true;\n\n @property({ type: Number, attribute: false })\n public messageIndex?: number;\n\n protected updated(_changedProperties: Map<PropertyKey, unknown>) {\n super.updated(_changedProperties);\n if (_changedProperties.has('message') || !this.hasAttribute('data-is-user')) {\n this.updateAlignment();\n }\n }\n\n private updateAlignment() {\n if (this.message) {\n this.setAttribute('data-is-user', String(this.message.role === 'user'));\n }\n }\n\n private copyToClipboard(text: string) {\n navigator.clipboard.writeText(text).catch(err => console.error('Failed to copy:', err));\n }\n\n private processMarkdownContent(markdownHtml: string): string {\n if (markdownHtml.includes('code-blocwrapper')) return markdownHtml;\n return markdownHtml.replace(/<pre><code([^>]*)>([\\s\\S]*?)<\\/code><\\/pre>/gi, (_, attrs, codeText) => `\n <div class=\"code-blocwrapper\">\n <div class=\"code-blocheader\">\n <wa-copy-button value=\"${this.escapeHtmlAttribute(codeText.trim())}\" size=\"small\" label=\"Copy code\"></wa-copy-button>\n </div>\n <div class=\"code-bloccontent\">\n <pre><code${attrs}>${codeText}</code></pre>\n </div>\n </div>`);\n }\n\n private escapeHtmlAttribute(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/'/g, ''');\n }\n\n private handleResend(e?: Event) {\n e?.preventDefault();\n e?.stopPropagation();\n if (!this.message) return;\n this.dispatchEvent(new CustomEvent('resend', {\n detail: { message: this.message, messageIndex: this.messageIndex },\n bubbles: true, composed: true\n }));\n }\n\n render() {\n if (!this.message) return html``;\n\n const message = this.message;\n const isUser = message.role === 'user';\n\n return html`\n <div class=\"message-wrapper ${isUser ? 'user' : 'assistant'} ${this.isStreaming ? 'streaming' : ''}\">\n ${when(this.showHeader && !isUser, () => html`\n <div class=\"message-header\">\n <div class=\"message-meta\">\n <wa-icon name=\"robot\" label=\"${message.role}\"></wa-icon>\n <span class=\"role-name\">${message.role}</span>\n </div>\n <div class=\"message-actions\">\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content)}\">\n <wa-icon slot=\"label\" name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n </div>\n </div>\n `)}\n <div class=\"message-content-wrapper ${isUser ? 'user' : ''}\">\n <div class=\"message-content\">\n ${unsafeHTML(this.processMarkdownContent(marked.parse(message.content || '') as string))}\n ${when(this.isStreaming, () => html`<span class=\"streaming-cursor\">▋</span>`)}\n </div>\n ${when(isUser, () => html`\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content)}\">\n <wa-icon name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Resend\"\n @click=\"${(e: Event) => this.handleResend(e)}\">\n <wa-icon name=\"rotate-right\" label=\"Resend\"></wa-icon>\n </wa-button>\n `)}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n max-width: 85%;\n box-sizing: border-box;\n animation: slideIn 0.2s ease-out;\n }\n\n :host([data-is-user=\"true\"]) { align-self: flex-end; }\n :host([data-is-user=\"false\"]) { align-self: flex-start; }\n\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .message-wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n box-sizing: border-box;\n }\n\n .message-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 0.5rem;\n padding: 0 0.5rem;\n }\n\n .message-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--wa-color-text-quiet);\n }\n\n .role-name { text-transform: capitalize; }\n\n .message-actions {\n display: flex;\n gap: 0.25rem;\n opacity: 0;\n transition: opacity 0.2s;\n }\n\n .message-wrapper:hover .message-actions,\n :host:hover .message-actions { opacity: 1; }\n\n .message-content-wrapper {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n width: 100%;\n }\n\n .message-content-wrapper.user {\n flex-direction: row;\n align-items: center;\n }\n\n .message-content {\n padding: 0.5rem 0.75rem;\n border-radius: 0.25rem;\n background-color: var(--wa-color-surface-default);\n word-break: breaword;\n overflow-wrap: breaword;\n max-width: 100%;\n box-sizing: border-box;\n line-height: 1.3;\n font-size: 0.9rem;\n }\n\n .message-content-wrapper.user .message-content {\n padding: 0.0625rem 0.75rem;\n background-color: var(--wa-color-brand-fill-quiet);\n color: var(--wa-color-text-normal);\n line-height: 1.4;\n flex: 1;\n }\n\n .message-content p { margin: 0; padding: 0; }\n .message-content ul, .message-content ol { margin: 0.25rem 0; padding-left: 1.25rem; }\n .message-content li { margin: 0.125rem 0; padding: 0; line-height: 1.3; }\n .message-content :first-child { margin-top: 0; padding-top: 0; }\n .message-content :last-child { margin-bottom: 0; padding-bottom: 0; }\n\n .message-content pre {\n white-space: pre-wrap;\n word-break: breaall;\n max-width: 100%;\n box-sizing: border-box;\n overflow-x: auto;\n margin: 0;\n }\n\n .message-content code {\n font-family: 'Courier New', monospace;\n background-color: var(--wa-color-surface-lowered);\n padding: 0.125rem 0.25rem;\n border-radius: 0.125rem;\n }\n\n .message-content pre code { background-color: transparent; padding: 0; display: block; }\n\n .code-blocwrapper {\n margin: 0.75rem 0;\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n border-radius: var(--wa-border-radius-m);\n background-color: var(--wa-color-surface-lowered);\n overflow: hidden;\n }\n\n .code-blocheader {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n padding: 0.375rem 0.5rem;\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n background-color: var(--wa-color-surface-default);\n }\n\n .code-bloccontent { padding: 0.75rem; overflow-x: auto; }\n .code-bloccontent pre { margin: 0; background-color: transparent; }\n .code-bloccontent code { background-color: transparent; padding: 0; }\n\n .streaming-cursor {\n display: inline-block;\n animation: blink 1s infinite;\n color: var(--wa-color-brand-50);\n }\n\n @keyframes blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-chat-message': AIChatMessage;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { when } from 'lit/directives/when.js';\n\n@customElement('lyra-ai-chat-input')\nexport class AIChatInput extends LitElement {\n @property({ type: String }) public value = '';\n @property({ type: Boolean }) public disabled = false;\n @property({ type: Boolean }) public busy = false;\n @property({ type: Boolean }) public hasProvider = true;\n\n @query('wa-textarea') private textareaElement?: any;\n\n private onInput(event: Event) {\n this.value = (event.target as any).value;\n this.dispatchEvent(new CustomEvent('input-change', { detail: { value: this.value }, bubbles: true, composed: true }));\n }\n\n private onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n private async send() {\n if (!this.value.trim() || this.disabled || !this.hasProvider) return;\n const messageValue = this.value;\n this.value = '';\n this.requestUpdate();\n await this.updateComplete;\n if (this.textareaElement) {\n this.textareaElement.value = '';\n this.textareaElement.focus();\n }\n this.dispatchEvent(new CustomEvent('send', { detail: { value: messageValue }, bubbles: true, composed: true }));\n }\n\n private cancel() {\n this.dispatchEvent(new CustomEvent('cancel', { bubbles: true, composed: true }));\n }\n\n render() {\n return html`\n <div class=\"input-container\">\n <div class=\"input-row\">\n <wa-textarea\n placeholder=\"Type a message... (Enter to send, Shift+Enter for new line)\"\n size=\"small\"\n resize=\"auto\"\n rows=\"1\"\n .value=\"${this.value}\"\n ?disabled=\"${this.disabled || !this.hasProvider}\"\n @input=\"${this.onInput}\"\n @keydown=\"${this.onKeyDown}\">\n </wa-textarea>\n ${when(this.busy, () => html`\n <wa-button appearance=\"plain\" size=\"small\" @click=\"${this.cancel}\">\n <wa-icon name=\"stop\" label=\"Stop\"></wa-icon>\n </wa-button>\n `)}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; width: 100%; }\n .input-container { margin-bottom: 0.25rem; margin-left: 0.25rem; }\n .input-row { display: flex; gap: 0.5rem; align-items: flex-end; }\n wa-textarea { flex: 1; min-width: 0; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-chat-input': AIChatInput;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { when } from 'lit/directives/when.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { ChatMessage } from '../../core/types';\nimport type { AgentResponseGroup, AgentResponseInfo } from '../agent-group-manager';\nimport './ai-chat-message';\n\n@customElement('lyra-ai-agent-response-group')\nexport class AIAgentResponseGroup extends LitElement {\n @property({ type: Object, attribute: false })\n public group?: AgentResponseGroup;\n\n @property({ type: Function, attribute: false })\n public findStreamingMessage?: (role: string) => ChatMessage | undefined;\n\n private copyToClipboard(text: string) {\n navigator.clipboard.writeText(text).catch(err => console.error('Failed to copy:', err));\n }\n\n private renderStatusIcon(status: AgentResponseInfo['status']) {\n switch (status) {\n case 'streaming': return html`<wa-icon name=\"spinner\" class=\"spinning\"></wa-icon>`;\n case 'completed': return html`<wa-icon name=\"check-circle\" class=\"status-success\"></wa-icon>`;\n case 'error': return html`<wa-icon name=\"exclamation-circle\" class=\"status-error\"></wa-icon>`;\n }\n }\n\n private renderCard(agentInfo: AgentResponseInfo, message: ChatMessage | undefined) {\n if (!message) {\n return html`\n <div class=\"agent-card status-${agentInfo.status}\">\n <div class=\"agent-card-header\">\n <wa-icon name=\"${agentInfo.icon}\" label=\"${agentInfo.label}\"></wa-icon>\n <span>${agentInfo.label}</span>\n ${this.renderStatusIcon(agentInfo.status)}\n </div>\n <div class=\"agent-card-content waiting\">Waiting for response...</div>\n </div>\n `;\n }\n\n return html`\n <div class=\"agent-card status-${agentInfo.status}\">\n <div class=\"agent-card-header\">\n <wa-icon name=\"${agentInfo.icon}\" label=\"${agentInfo.label}\"></wa-icon>\n <span>${agentInfo.label}</span>\n ${this.renderStatusIcon(agentInfo.status)}\n <div class=\"agent-card-actions\">\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content || '')}\">\n <wa-icon name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n </div>\n </div>\n <div class=\"agent-card-content\">\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${agentInfo.status === 'streaming'}\"\n .showHeader=\"${false}\"\n .messageIndex=\"${agentInfo.messageIndex}\">\n </lyra-ai-chat-message>\n </div>\n </div>\n `;\n }\n\n render() {\n if (!this.group) return html``;\n\n const agents = Array.from(this.group.agents.values());\n const completedCount = agents.filter(a => a.status === 'completed').length;\n const streamingCount = agents.filter(a => a.status === 'streaming').length;\n const errorCount = agents.filter(a => a.status === 'error').length;\n const allDone = agents.length > 0 && completedCount + errorCount === agents.length;\n const isSingle = agents.length === 1;\n\n return html`\n <div class=\"agent-response-group\">\n ${when(!isSingle, () => html`\n <div class=\"group-header\">\n <wa-icon name=\"robot\" label=\"Multiple Agents\"></wa-icon>\n <span>Multiple Agents</span>\n <span class=\"status-badge\">\n ${when(streamingCount > 0, () => html`<span class=\"streaming\">${streamingCount} responding</span>`)}\n ${when(allDone, () => html`<span class=\"done\">All completed (${completedCount})</span>`)}\n </span>\n </div>\n `)}\n <div class=\"group-content\">\n ${repeat(agents, a => a.role, (agentInfo) => {\n const message = agentInfo.message ||\n (agentInfo.status === 'streaming' && this.findStreamingMessage\n ? this.findStreamingMessage(agentInfo.role)\n : undefined);\n return this.renderCard(agentInfo, message);\n })}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; width: 100%; box-sizing: border-box; }\n\n .agent-response-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n }\n\n .group-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n background-color: var(--wa-color-surface-lowered);\n border: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n font-weight: 500;\n }\n\n .status-badge {\n display: flex;\n gap: 0.5rem;\n margin-left: auto;\n font-size: 0.875rem;\n }\n\n .streaming { color: var(--wa-color-brand-50); }\n .done { color: var(--wa-color-success-70); font-weight: 600; }\n\n .group-content {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n }\n\n .agent-card {\n display: flex;\n flex-direction: column;\n border: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n background-color: var(--wa-color-surface-default);\n }\n\n .agent-card.status-streaming { border-color: var(--wa-color-brand-border-quiet); }\n .agent-card.status-completed { border-color: var(--wa-color-success-border-quiet); }\n .agent-card.status-error { border-color: var(--wa-color-danger-border-quiet); }\n\n .agent-card-header {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.5rem;\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n background-color: var(--wa-color-surface-lowered);\n font-weight: 500;\n font-size: 0.875rem;\n }\n\n .agent-card-actions { margin-left: auto; display: flex; gap: 0.25rem; }\n .agent-card-content { padding: 0.375rem; }\n .waiting { padding: 1rem; text-align: center; color: var(--wa-color-text-quiet); }\n\n .spinning { animation: spin 1s linear infinite; }\n .status-success { color: var(--wa-color-success-60); }\n .status-error { color: var(--wa-color-danger-60); }\n\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-agent-response-group': AIAgentResponseGroup;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { ToolCall } from '../../core/types';\n\nexport interface ToolApprovalRequest {\n toolCalls: ToolCall[];\n message: string;\n}\n\nexport interface PendingApproval {\n role: string;\n request: ToolApprovalRequest;\n resolve: (approved: boolean) => void;\n alwaysAllowSelections: Map<string, boolean>;\n}\n\n@customElement('lyra-ai-tool-approval')\nexport class AIToolApproval extends LitElement {\n @property({ type: Map, attribute: false })\n public pendingApprovals = new Map<string, PendingApproval>();\n\n private approve(approvalId: string, approval: PendingApproval) {\n this.dispatchEvent(new CustomEvent('approve', {\n detail: { approvalId, approval },\n bubbles: true, composed: true\n }));\n approval.resolve(true);\n this.pendingApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private deny(approvalId: string, approval: PendingApproval) {\n approval.resolve(false);\n this.pendingApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private formatArgs(argsStr: string): string {\n let parsed: any = {};\n try { parsed = JSON.parse(argsStr); } catch { /* noop */ }\n return Object.entries(parsed).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(', ');\n }\n\n render() {\n if (this.pendingApprovals.size === 0) return html``;\n\n return html`\n <div class=\"approval-container\">\n ${Array.from(this.pendingApprovals.entries()).map(([id, approval]) => {\n const toolCalls = approval.request.toolCalls;\n const first = toolCalls[0];\n const summaryText = toolCalls.length === 1\n ? `AI wants to execute: ${first?.function.name}()`\n : `AI wants to execute ${toolCalls.length} tools`;\n\n return html`\n <wa-details class=\"approval-item\">\n <span slot=\"summary\" class=\"approval-summary\">\n <span>${summaryText}</span>\n <div class=\"approval-inline-actions\">\n <wa-button appearance=\"plain\" size=\"small\" variant=\"neutral\"\n @click=\"${(e: Event) => { e.stopPropagation(); this.deny(id, approval); }}\">\n <wa-icon name=\"xmark\" label=\"Deny\"></wa-icon>\n </wa-button>\n <wa-button appearance=\"plain\" size=\"small\" variant=\"success\"\n @click=\"${async (e: Event) => { e.stopPropagation(); this.approve(id, approval); }}\">\n <wa-icon name=\"check\" label=\"Approve\"></wa-icon>\n </wa-button>\n </div>\n </span>\n <div class=\"approval-detail\">\n <strong>${approval.role} wants to execute:</strong>\n <ul class=\"tool-list\">\n ${repeat(toolCalls, tc => tc.id, (tc) => {\n const argsStr = this.formatArgs(tc.function.arguments || '{}');\n const isSelected = approval.alwaysAllowSelections.get(tc.id) || false;\n return html`\n <li class=\"tool-item\">\n <label class=\"always-allow-label\">\n <wa-checkbox\n ?checked=\"${isSelected}\"\n @change=\"${(e: Event) => {\n approval.alwaysAllowSelections.set(tc.id, (e.target as any).checked);\n this.requestUpdate();\n }}\">\n </wa-checkbox>\n <span>Always allow</span>\n </label>\n <code>${tc.function.name}(${argsStr})</code>\n </li>\n `;\n })}\n </ul>\n </div>\n </wa-details>\n `;\n })}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .approval-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-warning-border-normal);\n background-color: var(--wa-color-warning-fill-quiet);\n }\n\n .approval-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n width: 100%;\n }\n\n .approval-inline-actions { display: flex; gap: 0.5rem; flex-shrink: 0; }\n\n .approval-detail {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.75rem 0;\n font-size: 0.875rem;\n }\n\n .tool-list { margin: 0.5rem 0 0 1.5rem; padding: 0; list-style: disc; }\n\n .tool-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin: 0.5rem 0;\n }\n\n .always-allow-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n cursor: pointer;\n }\n\n code {\n font-family: var(--wa-font-mono);\n font-size: 0.875rem;\n padding: 0.125rem 0.25rem;\n background-color: var(--wa-color-neutral-fill-subtle);\n border-radius: var(--wa-border-radius-s);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-tool-approval': AIToolApproval;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\n@customElement('lyra-ai-empty-state')\nexport class AIEmptyState extends LitElement {\n @property({ type: String }) public message = 'No AI provider configured';\n @property({ type: String }) public hint = 'Click the settings icon to configure an AI provider';\n\n render() {\n return html`\n <div class=\"empty-state\">\n <wa-icon name=\"robot\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>${this.message}</p>\n <p class=\"hint\">${this.hint}</p>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n text-align: center;\n color: var(--wa-color-text-quiet);\n }\n\n .empty-state p { margin: 0.5rem 0; }\n .hint { font-size: 0.875rem; opacity: 0.7; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-empty-state': AIEmptyState;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport type { TaskPlan, TaskStep, StepStatus } from '../core/types';\n\nconst STATUS_ICON: Record<StepStatus, string> = {\n running: 'spinner',\n completed: 'check-circle',\n failed: 'exclamation-circle',\n skipped: 'forward',\n pending: 'circle'\n};\n\nconst STATUS_COLOR: Record<StepStatus, string> = {\n running: 'var(--wa-color-brand-50)',\n completed: 'var(--wa-color-success-60)',\n failed: 'var(--wa-color-danger-60)',\n skipped: 'var(--wa-color-neutral-40)',\n pending: 'var(--wa-color-neutral-40)'\n};\n\n@customElement('lyra-ai-task-progress-panel')\nexport class AITaskProgressPanel extends LitElement {\n @property({ type: Object, attribute: false })\n public plan?: TaskPlan;\n\n @state()\n private expanded = true;\n\n render() {\n if (!this.plan) return html``;\n\n const completedCount = this.plan.steps.filter(s => s.status === 'completed').length;\n const totalCount = this.plan.steps.length;\n const progress = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0;\n\n return html`\n <div class=\"taspanel\">\n <div class=\"panel-header\" @click=\"${() => { this.expanded = !this.expanded; }}\">\n <wa-icon name=\"diagram-project\" label=\"Task Plan\"></wa-icon>\n <span class=\"panel-title\">Task Plan</span>\n <span class=\"progress-text\">${completedCount}/${totalCount}</span>\n <wa-progress-bar value=\"${progress}\" class=\"progress-bar\"></wa-progress-bar>\n <wa-icon name=\"${this.expanded ? 'chevron-up' : 'chevron-down'}\" label=\"toggle\"></wa-icon>\n </div>\n ${when(this.expanded, () => html`\n <div class=\"panel-body\">\n ${repeat(this.plan!.steps, s => s.id, (step) => html`\n <div class=\"step-row\">\n <wa-icon\n name=\"${STATUS_ICON[step.status] ?? 'circle'}\"\n style=\"color: ${STATUS_COLOR[step.status] ?? 'var(--wa-color-neutral-40)'}; ${step.status === 'running' ? 'animation: spin 1s linear infinite;' : ''}\">\n </wa-icon>\n <div class=\"step-info\">\n <span class=\"step-role\">${step.role}</span>\n <span class=\"step-task\">${step.subTask}</span>\n </div>\n ${when(step.revisions > 0, () => html`\n <span class=\"revisions-badge\">${step.revisions} rev</span>\n `)}\n </div>\n `)}\n </div>\n `)}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .taspanel {\n border: solid var(--wa-border-width-s) var(--wa-color-brand-border-quiet);\n border-radius: var(--wa-border-radius-m);\n background: var(--wa-color-surface-default);\n margin: 0.5rem 0;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n user-select: none;\n }\n\n .panel-title {\n font-weight: 500;\n flex: 0 0 auto;\n }\n\n .progress-text {\n font-size: 0.8rem;\n color: var(--wa-color-text-quiet);\n }\n\n .progress-bar {\n flex: 1;\n min-width: 60px;\n }\n\n .panel-body {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem 0.75rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .step-row {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n padding: 0.25rem 0;\n }\n\n .step-info {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n flex: 1;\n min-width: 0;\n }\n\n .step-role {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n text-transform: uppercase;\n }\n\n .step-task {\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .revisions-badge {\n font-size: 0.7rem;\n padding: 0.1rem 0.3rem;\n background: var(--wa-color-warning-fill-quiet);\n border-radius: var(--wa-border-radius-s);\n color: var(--wa-color-warning-70);\n flex-shrink: 0;\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-task-progress-panel': AITaskProgressPanel;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport type { Artifact, ArtifactType } from '../core/types';\n\nconst ARTIFACT_TYPE_ICON: Record<ArtifactType, string> = {\n code: 'code',\n json: 'brackets-curly',\n 'file-list': 'list',\n plan: 'diagram-project',\n review: 'magnifying-glass',\n text: 'file-lines'\n};\n\n@customElement('lyra-ai-workspace-panel')\nexport class AIWorkspacePanel extends LitElement {\n @property({ type: Array, attribute: false })\n public artifacts: Artifact[] = [];\n\n @state()\n private expanded = false;\n\n @state()\n private selectedArtifact?: Artifact;\n\n render() {\n if (this.artifacts.length === 0) return html``;\n\n return html`\n <div class=\"workspace-panel\">\n <div class=\"panel-header\" @click=\"${() => { this.expanded = !this.expanded; this.selectedArtifact = undefined; }}\">\n <wa-icon name=\"folder-open\" label=\"Workspace\"></wa-icon>\n <span class=\"panel-title\">Workspace</span>\n <span class=\"count-badge\">${this.artifacts.length} artifact${this.artifacts.length !== 1 ? 's' : ''}</span>\n <wa-icon name=\"${this.expanded ? 'chevron-up' : 'chevron-down'}\" label=\"toggle\"></wa-icon>\n </div>\n ${when(this.expanded, () => html`\n <div class=\"panel-body\">\n <div class=\"artifact-list\">\n ${repeat(this.artifacts, a => a.id, (artifact) => html`\n <div\n class=\"artifact-item ${this.selectedArtifact?.id === artifact.id ? 'selected' : ''}\"\n @click=\"${() => { this.selectedArtifact = this.selectedArtifact?.id === artifact.id ? undefined : artifact; }}\">\n <wa-icon name=\"${ARTIFACT_TYPE_ICON[artifact.type] ?? 'file-lines'}\" label=\"${artifact.type}\"></wa-icon>\n <div class=\"artifact-meta\">\n <span class=\"artifact-id\">${artifact.id}</span>\n <span class=\"artifact-producer\">by ${artifact.producedBy}</span>\n </div>\n <span class=\"artifact-type\">${artifact.type}</span>\n </div>\n ${when(this.selectedArtifact?.id === artifact.id, () => html`\n <div class=\"artifact-content\">\n <pre>${artifact.content}</pre>\n </div>\n `)}\n `)}\n </div>\n </div>\n `)}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .workspace-panel {\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n border-radius: var(--wa-border-radius-m);\n background: var(--wa-color-surface-default);\n margin: 0.5rem 0;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n user-select: none;\n }\n\n .panel-title { font-weight: 500; }\n\n .count-badge {\n font-size: 0.8rem;\n color: var(--wa-color-text-quiet);\n margin-left: auto;\n }\n\n .panel-body {\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .artifact-list { display: flex; flex-direction: column; }\n\n .artifact-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n }\n\n .artifact-item:hover { background: var(--wa-color-surface-lowered); }\n .artifact-item.selected { background: var(--wa-color-brand-fill-quiet); }\n\n .artifact-meta {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n }\n\n .artifact-id {\n font-size: 0.85rem;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .artifact-producer {\n font-size: 0.75rem;\n color: var(--wa-color-text-quiet);\n }\n\n .artifact-type {\n font-size: 0.75rem;\n padding: 0.1rem 0.3rem;\n background: var(--wa-color-surface-lowered);\n border-radius: var(--wa-border-radius-s);\n }\n\n .artifact-content {\n padding: 0.5rem 0.75rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n background: var(--wa-color-surface-lowered);\n }\n\n .artifact-content pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: breaword;\n font-size: 0.8rem;\n max-height: 200px;\n overflow-y: auto;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-workspace-panel': AIWorkspacePanel;\n }\n}\n","import { css, html, nothing, TemplateResult } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { LyraPart } from '@eclipse-lyra/core';\nimport { when } from 'lit/directives/when.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { commandRegistry as globalCommandRegistry } from '@eclipse-lyra/core';\nimport { taskService, uiContext, appSettings } from '@eclipse-lyra/core';\nimport { toastError } from '@eclipse-lyra/core';\n\nimport type { ChatMessage, ChatHistory, ChatProvider, TaskPlan, Artifact } from '../core/types';\nimport { TOPIC_AICONFIG_CHANGED, KEY_AI_CONFIG } from '../core/constants';\nimport { aiService } from '../service/ai-service';\n\nimport { SessionManager } from './session-manager';\nimport { StreamManager } from './stream-manager';\nimport { ProviderManager } from './provider-manager';\nimport { AgentGroupManager } from './agent-group-manager';\n\nimport './components/ai-chat-message';\nimport './components/ai-chat-input';\nimport './components/ai-agent-response-group';\nimport './components/ai-tool-approval';\nimport './components/ai-empty-state';\nimport './task-progress-panel';\nimport './workspace-panel';\nimport type { PendingApproval } from './components/ai-tool-approval';\n\n@customElement('lyra-aiview')\nexport class LyraAIView extends LyraPart {\n private sessionManager = new SessionManager();\n private scrollDebounceTimer?: ReturnType<typeof setTimeout>;\n\n private streamManager = new StreamManager(() => {\n this.requestUpdate();\n if (this.scrollDebounceTimer) clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = setTimeout(async () => {\n await this.updateComplete;\n this.scrollToBottom();\n this.scrollDebounceTimer = undefined;\n }, 100);\n });\n\n private providerManager = new ProviderManager(aiService);\n private agentGroupManager = new AgentGroupManager();\n\n @state() private busy = false;\n @state() private inputValue = '';\n @state() private requireToolApproval = true;\n @state() private showHistory = false;\n @state() private currentTaskPlan?: TaskPlan;\n @state() private currentArtifacts: Artifact[] = [];\n @state() private pendingToolApprovals = new Map<string, PendingApproval>();\n\n private toolApprovalAllowlist = new Set<string>();\n private abortController?: AbortController;\n\n protected async doBeforeUI() {\n this.subscribe(TOPIC_AICONFIG_CHANGED, () => this.onAIConfigChanged());\n await this.sessionManager.load();\n if (!this.sessionManager.getActiveSession()) {\n this.sessionManager.createSession();\n }\n await this.providerManager.initialize();\n await this.loadSettings();\n this.requestUpdate();\n }\n\n private async onAIConfigChanged() {\n await this.providerManager.initialize();\n await this.loadSettings();\n this.requestUpdate();\n }\n\n private async loadSettings() {\n const config = await appSettings.get(KEY_AI_CONFIG) as any || {};\n this.requireToolApproval = config.requireToolApproval !== false;\n const allowlist = await this.providerManager.loadToolApprovalAllowlist();\n this.toolApprovalAllowlist = new Set(allowlist);\n }\n\n private async scrollToBottom() {\n await this.updateComplete;\n const scroller = this.shadowRoot?.querySelector('wa-scroller.chat-messages') as any;\n if (!scroller) return;\n const container = scroller.shadowRoot?.querySelector('.scroll-container') as HTMLElement;\n if (container) {\n container.scrollTop = container.scrollHeight;\n } else if (scroller.scrollTo) {\n scroller.scrollTo({ top: scroller.scrollHeight, behavior: 'smooth' });\n }\n }\n\n private resetViewState() {\n this.inputValue = '';\n this.showHistory = false;\n this.currentTaskPlan = undefined;\n this.currentArtifacts = [];\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private createNewSession() {\n this.sessionManager.createSession();\n this.resetViewState();\n }\n\n private switchToSession(sessionId: string) {\n if (!this.sessionManager.switchToSession(sessionId)) return;\n this.resetViewState();\n }\n\n private deletePastSession(sessionId: string) {\n this.sessionManager.deletePastSession(sessionId);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async sendMessage() {\n const prompt = this.inputValue.trim();\n if (!prompt || this.busy) return;\n this.inputValue = '';\n await this.handlePrompt(prompt);\n }\n\n private async handleResend(message: ChatMessage) {\n if (!message || message.role !== 'user') return;\n await this.handlePrompt(message.content);\n }\n\n private cancelStream() {\n this.abortController?.abort();\n this.abortController = undefined;\n this.busy = false;\n this.streamManager.cancelUpdates();\n }\n\n public async handlePrompt(prompt: string): Promise<void> {\n if (prompt.startsWith('/')) {\n await this.runCommand(prompt.substring(1));\n return;\n }\n\n const selectedProvider = this.providerManager.getSelectedProvider();\n if (!selectedProvider) {\n toastError('Please configure an AI provider in settings');\n return;\n }\n\n const session = this.sessionManager.getActiveSession();\n if (!session) return;\n\n const message = aiService.createMessage(prompt);\n this.sessionManager.addMessage(message);\n\n if (session.history.length === 1) {\n this.sessionManager.setTitle(this.sessionManager.generateTitle(prompt));\n this.updateToolbar();\n }\n\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n this.busy = true;\n this.currentTaskPlan = undefined;\n this.currentArtifacts = [];\n\n this.abortController = new AbortController();\n const streamingAgents = new Map<string, number>();\n const chatContext: ChatHistory = { history: [...session.history] };\n const sessionId = session.id;\n\n const execContext = globalCommandRegistry.createExecutionContext();\n const callContext = uiContext.createChild({ ...execContext });\n const contributions = aiService.getAgentContributions();\n\n if (contributions.length === 0) {\n toastError('No agents are registered.');\n this.busy = false;\n return;\n }\n\n const matchingAgents = contributions.filter(c =>\n !c.canHandle || c.canHandle({ ...callContext.getProxy(), userPrompt: prompt })\n ).sort((a, b) => (b.priority || 0) - (a.priority || 0));\n\n if (matchingAgents.length === 0) {\n toastError(`No agents available. Available: ${contributions.map(c => c.role).join(', ')}`);\n this.busy = false;\n return;\n }\n\n const roles = matchingAgents.map(a => a.role);\n const currentSession = this.sessionManager.getActiveSession();\n if (!currentSession) return;\n\n const groupId = this.agentGroupManager.createGroup(\n sessionId,\n currentSession.history.length - 1,\n message,\n roles,\n (role: string) => {\n const contrib = contributions.find(c => c.role === role);\n return { label: (contrib as any)?.label || role, icon: (contrib as any)?.icon || 'robot' };\n }\n );\n\n taskService.runAsync('Calling AI assistant', async () => {\n return aiService.executeAgentWorkflow({\n chatContext,\n chatConfig: selectedProvider,\n callContext,\n execution: 'parallel',\n stream: true,\n signal: this.abortController!.signal,\n roles,\n requireToolApproval: this.requireToolApproval,\n onToolApprovalRequest: async (role: string, request: any): Promise<boolean> => {\n const allAllowed = request.toolCalls.every((tc: any) => this.toolApprovalAllowlist.has(tc.function.name));\n if (allAllowed) return true;\n\n return new Promise<boolean>((resolve) => {\n const approvalId = `approval-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n const pending: PendingApproval = {\n role,\n request,\n resolve,\n alwaysAllowSelections: new Map()\n };\n this.pendingToolApprovals.set(approvalId, pending);\n this.requestUpdate();\n });\n },\n onAgentStart: async (role: string) => {\n const streamIndex = this.streamManager.createStreamingMessage(role);\n streamingAgents.set(role, streamIndex);\n this.agentGroupManager.updateAgentStatus(groupId, role, 'streaming');\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n },\n onToken: (role: string, token: string) => {\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) this.streamManager.updateStreamingMessage(streamIndex, token);\n },\n onAgentComplete: async (role: string, completedMessage: ChatMessage) => {\n const targetSession = this.sessionManager.getActiveSession();\n if (!targetSession || targetSession.id !== sessionId) return;\n\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) {\n this.streamManager.completeStreamingMessage(streamIndex, completedMessage);\n const messageIndex = targetSession.history.length;\n this.sessionManager.addMessage(completedMessage);\n streamingAgents.delete(role);\n this.streamManager.removeStreamingMessage(streamIndex);\n this.agentGroupManager.updateAgentStatus(groupId, role, 'completed', completedMessage, messageIndex);\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n }\n },\n onAgentError: (role: string, error: Error) => {\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) {\n this.streamManager.removeStreamingMessage(streamIndex);\n streamingAgents.delete(role);\n }\n this.agentGroupManager.updateAgentStatus(groupId, role, 'error', { role, content: `Error: ${error.message}` });\n this.requestUpdate();\n toastError(`Agent ${role} error: ${error.message}`);\n }\n }).then(() => { this.agentGroupManager.clearCurrentGroup(); });\n }).catch((error: any) => {\n if (error?.name !== 'AbortError') toastError(`${error}`);\n }).finally(async () => {\n this.busy = false;\n this.abortController = undefined;\n this.streamManager.reset();\n this.agentGroupManager.clearCurrentGroup();\n this.requestUpdate();\n this.updateToolbar();\n });\n }\n\n private async runCommand(prompt: string) {\n const splits = prompt.trim().split(/\\s+/);\n if (splits.length === 0) return;\n const commandId = splits.shift()!;\n const command = globalCommandRegistry.getCommand(commandId);\n if (!command) { toastError(`Command not found: ${commandId}`); return; }\n const params: Record<string, string> = {};\n splits.forEach((c, i) => {\n if (command.parameters?.[i]) params[command.parameters[i].name] = c;\n });\n await globalCommandRegistry.execute(commandId, globalCommandRegistry.createExecutionContext(params));\n this.requestUpdate();\n }\n\n private handleToolApproval(e: CustomEvent) {\n const { approvalId, approval } = e.detail;\n const alwaysAllowed = Array.from((approval.alwaysAllowSelections as Map<string, boolean>).entries())\n .filter(([, v]) => v)\n .map(([k]) => k);\n alwaysAllowed.forEach(name => this.toolApprovalAllowlist.add(name));\n this.pendingToolApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private renderMessage(message: ChatMessage, index: number, isStreaming = false): TemplateResult {\n return html`\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${isStreaming}\"\n .showHeader=\"${true}\"\n .messageIndex=\"${index}\"\n @resend=\"${(e: CustomEvent) => this.handleResend(e.detail.message)}\">\n </lyra-ai-chat-message>\n `;\n }\n\n protected renderToolbar() {\n const past = this.sessionManager.getPastSessions();\n const session = this.sessionManager.getActiveSession();\n\n return html`\n <span style=\"flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:0.875rem;font-weight:500;padding:0 0.25rem;\">${session?.title || 'New Chat'}</span>\n <wa-button appearance=\"plain\" size=\"small\" title=\"New chat\"\n @click=\"${() => this.createNewSession()}\">\n <wa-icon name=\"plus\" label=\"New chat\"></wa-icon>\n </wa-button>\n ${past.length > 0 ? html`\n <wa-dropdown\n ?open=\"${this.showHistory}\"\n @wa-after-hide=\"${() => { this.showHistory = false; }}\"\n placement=\"bottom-start\">\n <wa-button slot=\"trigger\" appearance=\"plain\" size=\"small\" with-caret\n title=\"Chat history\"\n @click=\"${() => { this.showHistory = !this.showHistory; }}\">\n <wa-icon name=\"clock-rotate-left\" label=\"History\"></wa-icon>\n </wa-button>\n ${past.map(s => html`\n <wa-dropdown-item @click=\"${() => this.switchToSession(s.id)}\">\n <wa-icon name=\"message\" label=\"Session\" slot=\"icon\"></wa-icon>\n <span style=\"flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${s.title || 'Unnamed Chat'}</span>\n <wa-button slot=\"details\" appearance=\"plain\" size=\"small\" title=\"Delete\"\n @click=\"${(e: Event) => { e.stopPropagation(); this.deletePastSession(s.id); }}\">\n <wa-icon name=\"trash\" label=\"Delete\"></wa-icon>\n </wa-button>\n </wa-dropdown-item>\n `)}\n </wa-dropdown>\n ` : nothing}\n <lyra-command cmd=\"open_ai_config\" icon=\"gear\" title=\"AI Settings\"></lyra-command>\n `;\n }\n\n render() {\n const session = this.sessionManager.getActiveSession();\n const selectedProvider = this.providerManager.getSelectedProvider();\n\n return html`\n <div class=\"chat-container\">\n <wa-scroller class=\"chat-messages\" orientation=\"vertical\">\n <div class=\"chat-content\">\n ${when(!selectedProvider, () => html`\n <lyra-ai-empty-state\n message=\"No AI provider configured\"\n hint='Click the settings icon below to configure an AI provider'>\n </lyra-ai-empty-state>\n `, () => when(!session || session.history.length === 0, () => html`\n <lyra-ai-empty-state message=\"How can I help you?\" hint=\"\"></lyra-ai-empty-state>\n `, () => html`\n ${session!.history.map((message: ChatMessage, idx: number) => {\n const group = this.agentGroupManager.findGroupForUserMessage(session!.id, idx, message);\n if (group && message.role === 'user') {\n return html`\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${false}\"\n .showHeader=\"${true}\"\n .messageIndex=\"${idx}\"\n @resend=\"${(e: CustomEvent) => this.handleResend(e.detail.message)}\">\n </lyra-ai-chat-message>\n <lyra-ai-agent-response-group\n .group=\"${group}\"\n .findStreamingMessage=\"${(role: string) => this.streamManager.findStreamingMessage(role)}\">\n </lyra-ai-agent-response-group>\n `;\n }\n\n if (this.agentGroupManager.findGroupForMessage(session!.id, message.role, idx)) {\n return html``;\n }\n\n return this.renderMessage(message, idx);\n })}\n\n ${this.streamManager.getAllStreamingMessages()\n .filter(m => !this.agentGroupManager.getAllGroups()\n .some(g => g.sessionId === session!.id && g.agents.has(m.message.role)))\n .map(m => this.renderMessage(m.message, -1, m.isStreaming))}\n\n ${when(this.busy && this.streamManager.getAllStreamingMessages().length === 0, () => html`\n <div class=\"thinking-indicator\">\n <wa-progress-ring indeterminate size=\"small\"></wa-progress-ring>\n <span>Thinking…</span>\n </div>\n `)}\n `))}\n\n ${when(this.currentTaskPlan, () => html`\n <lyra-ai-task-progress-panel .plan=\"${this.currentTaskPlan}\"></lyra-ai-task-progress-panel>\n `)}\n\n ${when(this.currentArtifacts.length > 0, () => html`\n <lyra-ai-workspace-panel .artifacts=\"${this.currentArtifacts}\"></lyra-ai-workspace-panel>\n `)}\n </div>\n </wa-scroller>\n\n ${when(this.pendingToolApprovals.size > 0, () => html`\n <lyra-ai-tool-approval\n .pendingApprovals=\"${this.pendingToolApprovals}\"\n @approve=\"${(e: CustomEvent) => this.handleToolApproval(e)}\">\n </lyra-ai-tool-approval>\n `)}\n\n <div class=\"input-area\">\n <lyra-ai-chat-input\n .value=\"${this.inputValue}\"\n .busy=\"${this.busy}\"\n .disabled=\"${!selectedProvider}\"\n .hasProvider=\"${!!selectedProvider}\"\n @input-change=\"${(e: CustomEvent) => { this.inputValue = e.detail.value; }}\"\n @send=\"${(e: CustomEvent) => { this.inputValue = e.detail.value; this.sendMessage(); }}\"\n @cancel=\"${() => this.cancelStream()}\">\n </lyra-ai-chat-input>\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n background: var(--wa-color-surface-default);\n }\n\n .chat-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .chat-messages {\n flex: 1;\n overflow: hidden;\n }\n\n .chat-content {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 1rem;\n min-height: 100%;\n box-sizing: border-box;\n }\n\n .thinking-indicator {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n color: var(--wa-color-text-quiet);\n font-size: 0.875rem;\n }\n\n .input-area {\n padding: 0.5rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n flex-shrink: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-aiview': LyraAIView;\n }\n}\n","import { css, html } from 'lit';\nimport { customElement } from 'lit/decorators.js';\nimport { LyraElement } from '@eclipse-lyra/core';\nimport { subscribe, confirmDialog } from '@eclipse-lyra/core';\nimport { tokenUsageTracker, EMPTY_USAGE } from '../service/token-usage-tracker';\nimport { TOPIC_AI_STREAM_COMPLETE } from '../core/constants';\nimport type { ProviderTokenUsage } from '../core/types';\n\n@customElement('lyra-token-usage')\nexport class LyraTokenUsage extends LyraElement {\n private totalUsage: ProviderTokenUsage = { ...EMPTY_USAGE };\n private providerUsage: Record<string, ProviderTokenUsage> = {};\n\n connectedCallback() {\n super.connectedCallback();\n this.loadUsage();\n subscribe(TOPIC_AI_STREAM_COMPLETE, () => { this.loadUsage(); });\n }\n\n private async loadUsage() {\n this.totalUsage = await tokenUsageTracker.getTotalUsage();\n this.providerUsage = await tokenUsageTracker.getAllProviderUsage();\n this.requestUpdate();\n }\n\n private formatNumber(num: number): string {\n if (num >= 1_000_000) return (num / 1_000_000).toFixed(2) + 'M';\n if (num >= 1_000) return (num / 1_000).toFixed(1) + 'K';\n return num.toString();\n }\n\n private async handleReset() {\n if (await confirmDialog('Reset all token usage statistics?')) {\n await tokenUsageTracker.reset();\n await this.loadUsage();\n }\n }\n\n private renderStatItem(label: string, value: number) {\n return html`\n <div class=\"stat-item\">\n <span class=\"stat-label\">${label}</span>\n <span class=\"stat-value\">${this.formatNumber(value)}</span>\n </div>\n `;\n }\n\n protected render() {\n if (this.totalUsage.totalTokens === 0) return html``;\n\n return html`\n <wa-dropdown placement=\"top-end\" distance=\"8\">\n <wa-button slot=\"trigger\" appearance=\"plain\" size=\"small\" title=\"Token usage\">\n <wa-icon name=\"database\" label=\"Tokens\" slot=\"start\"></wa-icon>\n ${this.formatNumber(this.totalUsage.totalTokens)} tokens\n </wa-button>\n\n <h3>Token Usage</h3>\n\n <h6>Total</h6>\n <wa-dropdown-item>\n <span>All providers</span>\n <div class=\"stats-row\">\n ${this.renderStatItem('Prompt', this.totalUsage.promptTokens)}\n ${this.renderStatItem('Completion', this.totalUsage.completionTokens)}\n ${this.renderStatItem('Total', this.totalUsage.totalTokens)}\n ${this.renderStatItem('Requests', this.totalUsage.requestCount)}\n </div>\n </wa-dropdown-item>\n\n ${Object.keys(this.providerUsage).length > 0 ? html`\n <wa-divider></wa-divider>\n <h6>By Provider</h6>\n ${Object.entries(this.providerUsage).map(([name, usage]) => html`\n <wa-dropdown-item>\n <span class=\"provider-name\">${name}</span>\n <div class=\"stats-row\">\n ${this.renderStatItem('Prompt', usage.promptTokens)}\n ${this.renderStatItem('Completion', usage.completionTokens)}\n ${this.renderStatItem('Total', usage.totalTokens)}\n ${this.renderStatItem('Req', usage.requestCount)}\n </div>\n </wa-dropdown-item>\n `)}\n ` : ''}\n\n <wa-divider></wa-divider>\n <wa-dropdown-item variant=\"danger\" @click=\"${() => this.handleReset()}\">\n <wa-icon name=\"trash\" slot=\"icon\"></wa-icon>\n Reset statistics\n </wa-dropdown-item>\n </wa-dropdown>\n `;\n }\n\n static styles = css`\n :host { display: inline-block; }\n\n wa-dropdown::part(menu) { min-width: 320px; max-width: 420px; }\n\n h3 {\n padding: var(--wa-space-s) var(--wa-space-m);\n margin: 0;\n font-weight: 600;\n font-size: 0.95em;\n }\n\n h6 {\n padding: var(--wa-space-xs) var(--wa-space-m);\n margin: 0;\n font-weight: 600;\n font-size: 0.85em;\n color: var(--wa-color-neutral-text-subtle);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .provider-name { font-weight: 500; }\n\n .stats-row { display: flex; gap: var(--wa-space-m); font-size: 0.875rem; }\n\n .stat-item {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n .stat-label { font-size: 0.8em; color: var(--wa-color-neutral-text-subtle); }\n .stat-value { font-weight: 600; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-token-usage': LyraTokenUsage;\n }\n}\n","import { css, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport { LyraPart } from '@eclipse-lyra/core';\nimport { EditorInput } from '@eclipse-lyra/core';\nimport { appSettings, TOPIC_SETTINGS_CHANGED } from '@eclipse-lyra/core';\nimport { KEY_AI_CONFIG, TOPIC_AICONFIG_CHANGED, CID_CHAT_PROVIDERS } from '../../core/constants';\nimport { subscribe } from '@eclipse-lyra/core';\nimport { confirmDialog } from '@eclipse-lyra/core';\nimport { contributionRegistry } from '@eclipse-lyra/core';\nimport { ProviderFactory } from '../../providers/provider-factory';\nimport type { AIConfig, ChatProvider } from '../../core/types';\nimport type { ChatProviderContribution } from '../../core/interfaces';\n\n@customElement('lyra-ai-config-editor')\nexport class LyraAIConfigEditor extends LyraPart {\n @property({ attribute: false }) public input?: EditorInput;\n\n @state() private providers: ChatProvider[] = [];\n @state() private defaultProvider = '';\n @state() private hasChanges = false;\n @state() private availableModels: Array<{ id: string; name?: string }> = [];\n @state() private loadingModels = false;\n @state() private requireToolApproval = true;\n @state() private smartToolDetection = false;\n\n // Editing state for each provider field\n @state() private editingState: Record<number, Partial<ChatProvider>> = {};\n\n private aiConfig?: AIConfig;\n private providerFactory = new ProviderFactory();\n\n protected async doInitUI() {\n await this.loadConfig();\n subscribe(TOPIC_AICONFIG_CHANGED, () => this.loadConfig());\n subscribe(TOPIC_SETTINGS_CHANGED, () => this.loadConfig());\n }\n\n private async loadConfig() {\n const config = await appSettings.get(KEY_AI_CONFIG) as AIConfig | undefined;\n this.aiConfig = config;\n\n const contributed = (contributionRegistry.getContributions(CID_CHAT_PROVIDERS) as ChatProviderContribution[]).map(c => c.provider);\n const configProviders = config?.providers || [];\n const existingNames = new Set(configProviders.map(p => p.name));\n this.providers = [...configProviders, ...contributed.filter(p => !existingNames.has(p.name))];\n\n this.defaultProvider = config?.defaultProvider || '';\n this.requireToolApproval = config?.requireToolApproval !== false;\n this.smartToolDetection = config?.smartToolDetection !== undefined ? config.smartToolDetection : false;\n this.editingState = {};\n this.hasChanges = false;\n this.markDirty(false);\n }\n\n private getEditValue(index: number, field: keyof ChatProvider): string {\n const editing = this.editingState[index];\n if (editing && field in editing) return (editing as any)[field] ?? '';\n const provider = this.providers[index];\n return provider ? ((provider as any)[field] ?? '') : '';\n }\n\n private setEditValue(index: number, field: keyof ChatProvider, value: string) {\n this.editingState = {\n ...this.editingState,\n [index]: { ...(this.editingState[index] || {}), [field]: value }\n };\n this.providers = this.providers.map((p, i) =>\n i === index ? { ...p, [field]: value } : p\n );\n this.markDirtyAndUpdate();\n }\n\n private markDirtyAndUpdate() {\n this.hasChanges = true;\n this.markDirty(true);\n }\n\n private async fetchModels(index: number): Promise<void> {\n const provider = this.providers[index];\n if (!provider) return;\n this.loadingModels = true;\n this.availableModels = [];\n try {\n const instance = this.providerFactory.getProvider(provider);\n if (instance.getAvailableModels) {\n const models = await instance.getAvailableModels(provider);\n this.availableModels = Array.isArray(models) ? models : [];\n }\n } finally {\n this.loadingModels = false;\n }\n }\n\n private async saveConfig() {\n const updatedConfig: AIConfig = {\n ...(this.aiConfig ?? {}),\n defaultProvider: this.defaultProvider,\n providers: this.providers,\n requireToolApproval: this.requireToolApproval,\n smartToolDetection: this.smartToolDetection\n };\n await appSettings.set(KEY_AI_CONFIG, updatedConfig);\n this.aiConfig = updatedConfig;\n this.hasChanges = false;\n this.markDirty(false);\n }\n\n async save() {\n if (!this.hasChanges) return;\n await this.saveConfig();\n }\n\n private addProvider() {\n this.providers = [...this.providers, { name: 'new-provider', model: '', apiKey: '', chatApiEndpoint: '' }];\n this.markDirtyAndUpdate();\n }\n\n private async deleteProvider(index: number) {\n const provider = this.providers[index];\n if (!await confirmDialog(`Delete provider \"${provider.name}\"?`)) return;\n if (this.defaultProvider === provider.name) this.defaultProvider = '';\n this.providers = this.providers.filter((_, i) => i !== index);\n this.markDirtyAndUpdate();\n }\n\n private renderProviderField(index: number, field: keyof ChatProvider, type: 'text' | 'password' = 'text') {\n const value = this.getEditValue(index, field);\n return html`\n <wa-input\n type=\"${type}\"\n ?password-toggle=\"${type === 'password'}\"\n .value=\"${value}\"\n @input=\"${(e: Event) => this.setEditValue(index, field, (e.target as any).value)}\">\n </wa-input>\n `;\n }\n\n render() {\n return html`\n <div class=\"editor\">\n <div class=\"editor-header\">\n <h2>AI Providers</h2>\n <wa-button variant=\"brand\" appearance=\"filled\" @click=\"${this.addProvider}\">\n Add Provider\n </wa-button>\n </div>\n\n ${when(this.providers.length === 0, () => html`\n <div class=\"empty-state\"><p>No providers configured.</p></div>\n `, () => html`\n <div class=\"providers-list\">\n ${repeat(this.providers, (_, i) => i, (provider, index) => html`\n <div class=\"provider-card\">\n <div class=\"provider-card-header ${this.defaultProvider === provider.name ? 'is-default' : ''}\">\n <span class=\"provider-name\">${provider.name}</span>\n ${this.defaultProvider === provider.name\n ? html`<span class=\"default-badge\">Default</span>`\n : html`<wa-button appearance=\"plain\" size=\"small\" title=\"Set as default\"\n @click=\"${() => { this.defaultProvider = provider.name; this.markDirtyAndUpdate(); }}\">\n Set default\n </wa-button>`\n }\n <wa-button variant=\"danger\" appearance=\"plain\" size=\"small\"\n @click=\"${() => this.deleteProvider(index)}\">\n Delete\n </wa-button>\n </div>\n <div class=\"provider-fields\">\n <div class=\"field-row\">\n <label>Name</label>\n ${this.renderProviderField(index, 'name')}\n </div>\n <div class=\"field-row\">\n <label>Model</label>\n <div class=\"model-row\">\n ${this.renderProviderField(index, 'model')}\n <wa-button appearance=\"plain\" size=\"small\"\n @click=\"${async () => { await this.fetchModels(index); }}\"\n title=\"Fetch available models\">\n <wa-icon name=\"refresh\" label=\"Refresh\"></wa-icon>\n </wa-button>\n </div>\n ${when(this.loadingModels, () => html`\n <wa-progress-ring indeterminate size=\"small\"></wa-progress-ring>\n `)}\n ${when(this.availableModels.length > 0, () => html`\n <wa-dropdown\n @wa-select=\"${(e: CustomEvent) => {\n if (e.detail.item?.value) this.setEditValue(index, 'model', e.detail.item.value);\n }}\">\n <wa-button slot=\"trigger\" size=\"small\" appearance=\"plain\" with-caret>\n Select model\n </wa-button>\n ${this.availableModels.map(m => html`\n <wa-dropdown-item value=\"${m.id}\">${m.name || m.id}</wa-dropdown-item>\n `)}\n </wa-dropdown>\n `)}\n </div>\n <div class=\"field-row\">\n <label>API Endpoint</label>\n ${this.renderProviderField(index, 'chatApiEndpoint')}\n </div>\n <div class=\"field-row\">\n <label>API Key</label>\n ${this.renderProviderField(index, 'apiKey', 'password')}\n </div>\n </div>\n </div>\n `)}\n </div>\n `)}\n\n <div class=\"settings-section\">\n <h3>Tool Settings</h3>\n <wa-checkbox\n ?checked=\"${this.requireToolApproval}\"\n @change=\"${(e: Event) => { this.requireToolApproval = (e.target as any).checked; this.markDirtyAndUpdate(); }}\">\n Require approval before executing tools\n </wa-checkbox>\n <wa-checkbox\n ?checked=\"${this.smartToolDetection}\"\n @change=\"${(e: Event) => { this.smartToolDetection = (e.target as any).checked; this.markDirtyAndUpdate(); }}\">\n Smart tool detection (use ML to detect when tools are needed)\n </wa-checkbox>\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; height: 100%; overflow: auto; }\n\n .editor {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n padding: 1rem;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .editor-header h2 { margin: 0; font-size: 1.25rem; }\n\n .providers-list { display: flex; flex-direction: column; gap: 1rem; }\n\n .provider-card {\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n border-radius: var(--wa-border-radius-m);\n overflow: hidden;\n }\n\n .provider-card-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 0.75rem;\n background: var(--wa-color-surface-lowered);\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .provider-card-header.is-default {\n background: var(--wa-color-brand-fill-quiet);\n border-bottom-color: var(--wa-color-brand-border-quiet);\n }\n\n .default-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.1rem 0.4rem;\n background: var(--wa-color-brand-fill-loud);\n color: var(--wa-color-brand-on-loud);\n border-radius: var(--wa-border-radius-s);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .provider-name {\n font-weight: 500;\n flex: 1;\n }\n\n .provider-fields {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem;\n }\n\n .field-row {\n display: grid;\n grid-template-columns: 120px 1fr;\n align-items: start;\n gap: 0.5rem;\n }\n\n .field-row label {\n font-size: 0.875rem;\n color: var(--wa-color-text-quiet);\n padding-top: 0.4rem;\n }\n\n .model-row { display: flex; gap: 0.25rem; align-items: center; }\n .model-row wa-input { flex: 1; }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding-top: 1rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .settings-section h3 { margin: 0 0 0.5rem 0; font-size: 1rem; }\n\n .empty-state {\n display: flex;\n justify-content: center;\n padding: 3rem;\n color: var(--wa-color-text-subtle);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-config-editor': LyraAIConfigEditor;\n }\n}\n","import { html } from 'lit';\nimport { rootContext } from '@eclipse-lyra/core';\nimport { aiService } from './service/ai-service';\nimport { contributionRegistry } from '@eclipse-lyra/core';\nimport type { HTMLContribution } from '@eclipse-lyra/core';\nimport { editorRegistry } from '@eclipse-lyra/core';\nimport type { EditorInput } from '@eclipse-lyra/core';\nimport { registerAll, appSettings } from '@eclipse-lyra/core';\nimport { TOOLBAR_BOTTOM, TOOLBAR_MAIN_RIGHT, SIDEBAR_AUXILIARY } from '@eclipse-lyra/core';\nimport { CID_AGENTS, KEY_AI_CONFIG } from './core/constants';\nimport type { AgentContribution, AgentToolsConfig } from './core/interfaces';\nimport type { AIConfig } from './core/types';\nimport GENERAL_SYS_PROMPT from './general-assistant-prompt.txt?raw';\n\nimport './chat-provider-contributions';\nimport './prompt-enhancer-contributions';\nimport './view/aiview';\nimport './view/token-usage';\nimport './view/components/ai-config-editor';\n\ncontributionRegistry.registerContribution(SIDEBAR_AUXILIARY, {\n name: 'aiview',\n label: 'AI Assistant',\n icon: 'robot',\n component: (id: string) => html`<lyra-aiview id=\"${id}\"></lyra-aiview>`\n});\n\ncontributionRegistry.registerContribution(CID_AGENTS, {\n label: 'App Support',\n description: 'General-purpose assistant that can answer questions and execute app commands',\n role: 'appsupport',\n priority: 100,\n icon: 'question-circle',\n sysPrompt: GENERAL_SYS_PROMPT,\n tools: async () => {\n const config = await appSettings.get(KEY_AI_CONFIG) as AIConfig | undefined;\n return {\n enabled: true,\n smartToolDetection: config?.smartToolDetection ?? false\n } as AgentToolsConfig;\n }\n} as AgentContribution);\n\ncontributionRegistry.registerContribution(TOOLBAR_BOTTOM, {\n target: TOOLBAR_BOTTOM,\n label: 'Token Usage',\n html: '<lyra-token-usage></lyra-token-usage>'\n} as HTMLContribution);\n\neditorRegistry.registerEditorInputHandler({\n editorId: 'system.ai-config-editor',\n label: 'AI Config',\n ranking: 1000,\n canHandle: (input: EditorInput) => input.key === '.system.ai-config',\n handle: async (input: EditorInput) => {\n input.widgetFactory = () => html`<lyra-ai-config-editor .input=\"${input}\"></lyra-ai-config-editor>`;\n return input;\n }\n});\n\nregisterAll({\n command: {\n id: 'open_ai_config',\n name: 'Open AI Configuration',\n description: 'Open the AI system configuration editor',\n parameters: []\n },\n handler: {\n execute: (_context: any) => {\n const editorInput: EditorInput = {\n title: 'AI Settings',\n data: {},\n key: '.system.ai-config',\n icon: 'robot',\n state: {}\n } as EditorInput;\n editorRegistry.loadEditor(editorInput).then();\n }\n },\n contribution: {\n target: TOOLBAR_MAIN_RIGHT,\n icon: 'robot',\n label: 'AI Config'\n }\n});\n\nrootContext.put('aiService', aiService);\n"],"names":["aiService","__decorateClass","globalCommandRegistry"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-system-extension-Rr1JZnwv.js","sources":["../src/general-assistant-prompt.txt?raw","../src/chat-provider-contributions.ts","../src/prompt-enhancer-contributions.ts","../src/view/session-manager.ts","../src/view/stream-manager.ts","../src/view/provider-manager.ts","../src/view/agent-group-manager.ts","../src/view/components/ai-chat-message.ts","../src/view/components/ai-chat-input.ts","../src/view/components/ai-agent-response-group.ts","../src/view/components/ai-tool-approval.ts","../src/view/components/ai-empty-state.ts","../src/view/task-progress-panel.ts","../src/view/workspace-panel.ts","../src/view/aiview.ts","../src/view/token-usage.ts","../src/view/components/ai-config-editor.ts","../src/ai-system-extension.ts"],"sourcesContent":["export default \"You are an assistant in a web application with workspace, editors, and AI chat.\\n\\n**Tools:**\\nCommands are exposed as AI-callable tools. Tools are context-aware - available commands depend on active editor, selected files, and workspace state.\\n\\n**Tool Usage Rules:**\\n1. If tools are available and match the request, use them - don't describe manual steps\\n2. Read tool descriptions/parameters to select the correct tool\\n3. Call tools in sequence for multi-step tasks\\n4. After successful tool execution, provide a final response - don't loop or call more tools unless explicitly requested\\n5. If no tools are available, explain what context is needed\\n\\nKeep responses concise. Use tools when available rather than discussing alternatives.\\n\\n\"","import { contributionRegistry } from '@eclipse-lyra/core';\nimport { CID_CHAT_PROVIDERS } from './core/constants';\nimport type { ChatProviderContribution } from './core/interfaces';\n\nconst providers: Array<{ label: string; name: string; model: string; chatApiEndpoint: string; apiKey: string; parameters?: Record<string, any> }> = [\n { label: 'Ollama (Local)', name: 'ollama', model: 'gemma3:12b', chatApiEndpoint: 'https://<your-server>/v1/chat/completions', apiKey: '' },\n { label: 'OpenWebUI (Self Hosted)', name: 'openwebui', model: 'gemma3:12b', chatApiEndpoint: 'https://<your-server>/api/v1/chat/completion', apiKey: '' },\n { label: 'OpenAI', name: 'openai', model: 'gpt-4.1', chatApiEndpoint: 'https://api.openai.com/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'Groq', name: 'groq', model: 'llama-3.1-8b-instant', chatApiEndpoint: 'https://api.groq.com/openai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'Cerebras', name: 'cerebras', model: 'llama3.1-8b', chatApiEndpoint: 'https://api.cerebras.ai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'WebLLM', name: 'webllm', model: 'gemma-2-9b-it-q4f16_1-MLC', chatApiEndpoint: '', apiKey: '', parameters: { context_window_size: 4096 } },\n { label: 'Mistral', name: 'mistral', model: 'mistral-large-latest', chatApiEndpoint: 'https://api.mistral.ai/v1/chat/completions', apiKey: '<your api key>' },\n { label: 'LiteLLM', name: 'litellm', model: 'gpt-3.5-turbo', chatApiEndpoint: 'https://<your-server>/v1/chat/completions', apiKey: '<your api key>' },\n];\n\nfor (const { label, ...provider } of providers) {\n contributionRegistry.registerContribution<ChatProviderContribution>(CID_CHAT_PROVIDERS, {\n target: CID_CHAT_PROVIDERS,\n label,\n provider\n });\n}\n","import { contributionRegistry, workspaceService, editorRegistry } from '@eclipse-lyra/core';\nimport type { ExecutionContext } from '@eclipse-lyra/core';\nimport { CID_PROMPT_ENHANCERS } from './core/constants';\nimport type { PromptEnhancer, PromptEnhancerContribution } from './core/interfaces';\n\nconst appStateEnhancer: PromptEnhancer = {\n priority: 20,\n enhance: async (prompt: string, _context: ExecutionContext) => {\n try {\n const workspace = await workspaceService.getWorkspace();\n const activeEditor = editorRegistry.getEditorArea()?.getActiveEditor();\n const appState = {\n workspace: workspace?.getName() || null,\n activeEditor: activeEditor ? {\n title: (activeEditor as any).input?.title || null,\n editorId: (activeEditor as any).input?.editorId || null\n } : null\n };\n return `${prompt}\\n\\n***App's state:***\\n${JSON.stringify(appState, null, 2)}`;\n } catch {\n return prompt;\n }\n }\n};\n\ncontributionRegistry.registerContribution(CID_PROMPT_ENHANCERS, {\n label: 'App State Enhancer',\n enhancer: appStateEnhancer\n} as PromptEnhancerContribution);\n","import { appSettings } from \"@eclipse-lyra/core\";\nimport type { ChatMessage } from \"../core/types\";\n\nexport interface Session {\n id: string;\n history: ChatMessage[];\n title: string;\n createdAt: number;\n updatedAt: number;\n}\n\nexport class SessionManager {\n private activeSession: Session | null = null;\n private pastSessions: Session[] = [];\n\n async load(): Promise<void> {\n const saved = await appSettings.get('aiChatSessions') as any;\n if (!saved) return;\n\n if (saved.active && Array.isArray(saved.history)) {\n this.activeSession = saved.active;\n } else if (saved.activeSessionId && Array.isArray(saved.sessions)) {\n this.activeSession = saved.sessions.find((s: Session) => s.id === saved.activeSessionId) || null;\n this.pastSessions = saved.sessions.filter((s: Session) => s.id !== saved.activeSessionId);\n } else if (Array.isArray(saved.all)) {\n const [first, ...rest] = (saved.all as Session[]).sort((a, b) => b.updatedAt - a.updatedAt);\n this.activeSession = first || null;\n this.pastSessions = rest;\n }\n }\n\n async persist(): Promise<void> {\n const all: Session[] = [];\n if (this.activeSession) all.push(this.activeSession);\n all.push(...this.pastSessions);\n\n await appSettings.set('aiChatSessions', {\n all,\n activeSessionId: this.activeSession?.id || null\n });\n }\n\n createSession(): Session {\n const session: Session = {\n id: `session-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`,\n history: [],\n title: 'New Chat',\n createdAt: Date.now(),\n updatedAt: Date.now()\n };\n if (this.activeSession) {\n this.pastSessions.unshift(this.activeSession);\n }\n this.activeSession = session;\n this.persist();\n return session;\n }\n\n getActiveSession(): Session | null {\n return this.activeSession;\n }\n\n getActiveSessionId(): string {\n return this.activeSession?.id || '';\n }\n\n switchToSession(sessionId: string): boolean {\n if (this.activeSession?.id === sessionId) return true;\n\n const idx = this.pastSessions.findIndex(s => s.id === sessionId);\n if (idx === -1) return false;\n\n const [target] = this.pastSessions.splice(idx, 1);\n if (!target) return false;\n\n if (this.activeSession) this.pastSessions.unshift(this.activeSession);\n this.activeSession = target;\n\n this.persist();\n return true;\n }\n\n getPastSessions(): Session[] {\n return this.pastSessions;\n }\n\n deletePastSession(sessionId: string): boolean {\n const idx = this.pastSessions.findIndex(s => s.id === sessionId);\n if (idx === -1) return false;\n this.pastSessions.splice(idx, 1);\n this.persist();\n return true;\n }\n\n addMessage(message: ChatMessage): void {\n if (!this.activeSession) return;\n this.activeSession.history.push(message);\n this.activeSession.updatedAt = Date.now();\n this.persist();\n }\n\n setTitle(title: string): void {\n if (!this.activeSession) return;\n this.activeSession.title = title;\n this.persist();\n }\n\n generateTitle(prompt: string): string {\n const trimmed = prompt.trim();\n if (!trimmed) return 'New Chat';\n return trimmed.length <= 30 ? trimmed : trimmed.substring(0, 30).trim() + '...';\n }\n\n deleteActiveAndSwitchToFirst(): void {\n if (!this.activeSession) return;\n this.activeSession = this.pastSessions.shift() || null;\n if (!this.activeSession) {\n this.createSession();\n }\n this.persist();\n }\n}\n","import type { ChatMessage } from \"../core/types\";\n\nexport interface StreamingMessage {\n message: ChatMessage;\n isStreaming: boolean;\n}\n\nexport class StreamManager {\n private streamingMessages = new Map<number, StreamingMessage>();\n private currentIndex = -1;\n private rafHandle?: number;\n private pendingUpdate = false;\n private onUpdate?: () => void;\n\n constructor(onUpdate?: () => void) {\n this.onUpdate = onUpdate;\n }\n\n createStreamingMessage(role: string): number {\n const index = ++this.currentIndex;\n this.streamingMessages.set(index, { message: { role, content: '' }, isStreaming: true });\n return index;\n }\n\n updateStreamingMessage(index: number, token: string): void {\n const msg = this.streamingMessages.get(index);\n if (!msg) return;\n msg.message.content += token;\n this.scheduleUpdate();\n }\n\n completeStreamingMessage(index: number, message: ChatMessage): void {\n const msg = this.streamingMessages.get(index);\n if (!msg) return;\n msg.message = message;\n msg.isStreaming = false;\n }\n\n removeStreamingMessage(index: number): void {\n this.streamingMessages.delete(index);\n }\n\n findStreamingMessage(role: string): ChatMessage | undefined {\n return Array.from(this.streamingMessages.values()).find(m => m.message.role === role)?.message;\n }\n\n getAllStreamingMessages(): StreamingMessage[] {\n return Array.from(this.streamingMessages.values());\n }\n\n scheduleUpdate(): void {\n if (this.pendingUpdate) return;\n this.pendingUpdate = true;\n this.rafHandle = requestAnimationFrame(() => {\n this.pendingUpdate = false;\n this.onUpdate?.();\n });\n }\n\n cancelUpdates(): void {\n if (this.rafHandle !== undefined) {\n cancelAnimationFrame(this.rafHandle);\n this.rafHandle = undefined;\n this.pendingUpdate = false;\n }\n }\n\n reset(): void {\n this.streamingMessages.clear();\n this.cancelUpdates();\n this.currentIndex = -1;\n }\n}\n","import { appSettings } from \"@eclipse-lyra/core\";\nimport type { ChatProvider } from \"../core/types\";\nimport type { AIService } from \"../service/ai-service\";\nimport { KEY_AI_CONFIG } from \"../core/constants\";\nimport { ProviderFactory } from \"../providers/provider-factory\";\n\nexport interface AIViewSettings {\n requireToolApproval?: boolean;\n toolApprovalAllowlist?: string[];\n}\n\nexport interface ModelInfo {\n id: string;\n name?: string;\n}\n\nconst VIEW_SETTINGS_KEY = 'aiViewChat';\n\nexport class ProviderManager {\n private providers: ChatProvider[] = [];\n private selectedProvider?: ChatProvider;\n private availableModels: ModelInfo[] = [];\n private loadingModels = false;\n\n private providerFactory = new ProviderFactory();\n\n constructor(private aiService: AIService) {}\n\n async initialize(): Promise<void> {\n this.providers = await this.aiService.getProviders() || [];\n const defaultProvider = await this.aiService.getDefaultProvider();\n if (defaultProvider) {\n this.selectedProvider = defaultProvider;\n }\n }\n\n getProviders(): ChatProvider[] { return this.providers; }\n getSelectedProvider(): ChatProvider | undefined { return this.selectedProvider; }\n setSelectedProvider(provider: ChatProvider): void { this.selectedProvider = provider; }\n getAvailableModels(): ModelInfo[] { return this.availableModels; }\n isLoadingModels(): boolean { return this.loadingModels; }\n\n async saveSettings(providerName: string, model: string, apiKey?: string, requireToolApproval?: boolean, toolApprovalAllowlist?: string[]): Promise<void> {\n const current: AIViewSettings = await appSettings.get(VIEW_SETTINGS_KEY) || {};\n const settings: AIViewSettings = { ...current };\n if (requireToolApproval !== undefined) settings.requireToolApproval = requireToolApproval;\n if (toolApprovalAllowlist !== undefined) settings.toolApprovalAllowlist = toolApprovalAllowlist;\n await appSettings.set(VIEW_SETTINGS_KEY, settings);\n\n const provider = this.providers.find(p => p.name === providerName);\n if (provider) {\n const updated = { ...provider, model, ...(apiKey !== undefined && { apiKey }) };\n this.selectedProvider = updated;\n await this.updateProviderInAIConfig(providerName, { model, ...(apiKey !== undefined && { apiKey }) });\n await this.aiService.setDefaultProvider(providerName);\n }\n }\n\n private async updateProviderInAIConfig(providerName: string, updates: { model?: string; apiKey?: string }): Promise<void> {\n const aiConfig = await appSettings.get(KEY_AI_CONFIG) || {};\n if (!aiConfig.providers || !Array.isArray(aiConfig.providers)) return;\n const idx = aiConfig.providers.findIndex((p: any) => p.name === providerName);\n if (idx >= 0) {\n aiConfig.providers[idx] = { ...aiConfig.providers[idx], ...updates };\n await appSettings.set(KEY_AI_CONFIG, aiConfig);\n }\n }\n\n async loadToolApprovalAllowlist(): Promise<string[]> {\n const settings: AIViewSettings = await appSettings.get(VIEW_SETTINGS_KEY) || {};\n return settings.toolApprovalAllowlist || [];\n }\n\n async fetchModels(providerName: string): Promise<void> {\n const provider = this.providers.find(p => p.name === providerName);\n if (!provider) return;\n\n this.loadingModels = true;\n this.availableModels = [];\n\n try {\n const baseProvider = this.providerFactory.getProvider(provider);\n this.availableModels = await baseProvider.getAvailableModels?.(provider) ?? [];\n } finally {\n this.loadingModels = false;\n }\n }\n}\n","import type { ChatMessage } from \"../core/types\";\n\nexport interface AgentResponseInfo {\n role: string;\n label: string;\n icon: string;\n status: 'streaming' | 'completed' | 'error';\n message?: ChatMessage;\n messageIndex?: number;\n}\n\nexport interface AgentResponseGroup {\n id: string;\n sessionId: string;\n userMessageIndex: number;\n userMessage: ChatMessage;\n timestamp: Date;\n agents: Map<string, AgentResponseInfo>;\n messageIndices: Map<string, number>;\n}\n\nexport class AgentGroupManager {\n private groups = new Map<string, AgentResponseGroup>();\n private currentGroupId?: string;\n\n createGroup(\n sessionId: string,\n userMessageIndex: number,\n userMessage: ChatMessage,\n roles: string[],\n getAgentMetadata: (role: string) => { label: string; icon: string }\n ): string {\n const groupId = `group-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n this.currentGroupId = groupId;\n\n const group: AgentResponseGroup = {\n id: groupId,\n sessionId,\n userMessageIndex,\n userMessage,\n timestamp: new Date(),\n agents: new Map(),\n messageIndices: new Map()\n };\n\n roles.forEach(role => {\n const { label, icon } = getAgentMetadata(role);\n group.agents.set(role, { role, label, icon, status: 'streaming' });\n });\n\n this.groups.set(groupId, group);\n return groupId;\n }\n\n getGroup(groupId: string): AgentResponseGroup | undefined {\n return this.groups.get(groupId);\n }\n\n updateAgentStatus(groupId: string, role: string, status: AgentResponseInfo['status'], message?: ChatMessage, messageIndex?: number): void {\n const group = this.groups.get(groupId);\n if (!group) return;\n const agentInfo = group.agents.get(role);\n if (!agentInfo) return;\n agentInfo.status = status;\n if (message) agentInfo.message = message;\n if (messageIndex !== undefined) {\n agentInfo.messageIndex = messageIndex;\n group.messageIndices.set(role, messageIndex);\n }\n }\n\n getGroupsForSession(sessionId: string): AgentResponseGroup[] {\n return Array.from(this.groups.values()).filter(g => g.sessionId === sessionId);\n }\n\n findGroupForUserMessage(sessionId: string, userMessageIndex: number, userMessage: ChatMessage): AgentResponseGroup | undefined {\n return Array.from(this.groups.values()).find(\n g => g.sessionId === sessionId && g.userMessageIndex === userMessageIndex && g.userMessage === userMessage\n );\n }\n\n findGroupForMessage(sessionId: string, messageRole: string, messageIndex: number): AgentResponseGroup | undefined {\n return Array.from(this.groups.values()).find(\n g => g.sessionId === sessionId && g.messageIndices.get(messageRole) === messageIndex\n );\n }\n\n getCurrentGroupId(): string | undefined { return this.currentGroupId; }\n setCurrentGroupId(groupId: string | undefined): void { this.currentGroupId = groupId; }\n clearCurrentGroup(): void { this.currentGroupId = undefined; }\n getAllGroups(): AgentResponseGroup[] { return Array.from(this.groups.values()); }\n\n clearAll(): void {\n this.groups.clear();\n this.currentGroupId = undefined;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { unsafeHTML } from 'lit/directives/unsafe-html.js';\nimport { when } from 'lit/directives/when.js';\nimport { marked } from 'marked';\nimport type { ChatMessage } from '../../core/types';\n\n@customElement('lyra-ai-chat-message')\nexport class AIChatMessage extends LitElement {\n @property({ type: Object, attribute: false })\n public message?: ChatMessage;\n\n @property({ type: Boolean })\n public isStreaming = false;\n\n @property({ type: Boolean })\n public showHeader = true;\n\n @property({ type: Number, attribute: false })\n public messageIndex?: number;\n\n protected updated(_changedProperties: Map<PropertyKey, unknown>) {\n super.updated(_changedProperties);\n if (_changedProperties.has('message') || !this.hasAttribute('data-is-user')) {\n this.updateAlignment();\n }\n }\n\n private updateAlignment() {\n if (this.message) {\n this.setAttribute('data-is-user', String(this.message.role === 'user'));\n }\n }\n\n private copyToClipboard(text: string) {\n navigator.clipboard.writeText(text).catch(err => console.error('Failed to copy:', err));\n }\n\n private processMarkdownContent(markdownHtml: string): string {\n if (markdownHtml.includes('code-blocwrapper')) return markdownHtml;\n return markdownHtml.replace(/<pre><code([^>]*)>([\\s\\S]*?)<\\/code><\\/pre>/gi, (_, attrs, codeText) => `\n <div class=\"code-blocwrapper\">\n <div class=\"code-blocheader\">\n <wa-copy-button value=\"${this.escapeHtmlAttribute(codeText.trim())}\" size=\"small\" label=\"Copy code\"></wa-copy-button>\n </div>\n <div class=\"code-bloccontent\">\n <pre><code${attrs}>${codeText}</code></pre>\n </div>\n </div>`);\n }\n\n private escapeHtmlAttribute(text: string): string {\n return text.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/\"/g, '"').replace(/'/g, ''');\n }\n\n private handleResend(e?: Event) {\n e?.preventDefault();\n e?.stopPropagation();\n if (!this.message) return;\n this.dispatchEvent(new CustomEvent('resend', {\n detail: { message: this.message, messageIndex: this.messageIndex },\n bubbles: true, composed: true\n }));\n }\n\n render() {\n if (!this.message) return html``;\n\n const message = this.message;\n const isUser = message.role === 'user';\n\n return html`\n <div class=\"message-wrapper ${isUser ? 'user' : 'assistant'} ${this.isStreaming ? 'streaming' : ''}\">\n ${when(this.showHeader && !isUser, () => html`\n <div class=\"message-header\">\n <div class=\"message-meta\">\n <wa-icon name=\"robot\" label=\"${message.role}\"></wa-icon>\n <span class=\"role-name\">${message.role}</span>\n </div>\n <div class=\"message-actions\">\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content)}\">\n <wa-icon slot=\"label\" name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n </div>\n </div>\n `)}\n <div class=\"message-content-wrapper ${isUser ? 'user' : ''}\">\n <div class=\"message-content\">\n ${unsafeHTML(this.processMarkdownContent(marked.parse(message.content || '') as string))}\n ${when(this.isStreaming, () => html`<span class=\"streaming-cursor\">▋</span>`)}\n </div>\n ${when(isUser, () => html`\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content)}\">\n <wa-icon name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Resend\"\n @click=\"${(e: Event) => this.handleResend(e)}\">\n <wa-icon name=\"rotate-right\" label=\"Resend\"></wa-icon>\n </wa-button>\n `)}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n width: 100%;\n max-width: 85%;\n box-sizing: border-box;\n animation: slideIn 0.2s ease-out;\n }\n\n :host([data-is-user=\"true\"]) { align-self: flex-end; }\n :host([data-is-user=\"false\"]) { align-self: flex-start; }\n\n @keyframes slideIn {\n from { opacity: 0; transform: translateY(10px); }\n to { opacity: 1; transform: translateY(0); }\n }\n\n .message-wrapper {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n box-sizing: border-box;\n }\n\n .message-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n gap: 0.5rem;\n padding: 0 0.5rem;\n }\n\n .message-meta {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n font-size: 0.875rem;\n color: var(--wa-color-text-quiet);\n }\n\n .role-name { text-transform: capitalize; }\n\n .message-actions {\n display: flex;\n gap: 0.25rem;\n opacity: 0;\n transition: opacity 0.2s;\n }\n\n .message-wrapper:hover .message-actions,\n :host:hover .message-actions { opacity: 1; }\n\n .message-content-wrapper {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n width: 100%;\n }\n\n .message-content-wrapper.user {\n flex-direction: row;\n align-items: center;\n }\n\n .message-content {\n padding: 0.5rem 0.75rem;\n border-radius: 0.25rem;\n background-color: var(--wa-color-surface-default);\n word-break: breaword;\n overflow-wrap: breaword;\n max-width: 100%;\n box-sizing: border-box;\n line-height: 1.3;\n font-size: 0.9rem;\n }\n\n .message-content-wrapper.user .message-content {\n padding: 0.0625rem 0.75rem;\n background-color: var(--wa-color-brand-fill-quiet);\n color: var(--wa-color-text-normal);\n line-height: 1.4;\n flex: 1;\n }\n\n .message-content p { margin: 0; padding: 0; }\n .message-content ul, .message-content ol { margin: 0.25rem 0; padding-left: 1.25rem; }\n .message-content li { margin: 0.125rem 0; padding: 0; line-height: 1.3; }\n .message-content :first-child { margin-top: 0; padding-top: 0; }\n .message-content :last-child { margin-bottom: 0; padding-bottom: 0; }\n\n .message-content pre {\n white-space: pre-wrap;\n word-break: breaall;\n max-width: 100%;\n box-sizing: border-box;\n overflow-x: auto;\n margin: 0;\n }\n\n .message-content code {\n font-family: 'Courier New', monospace;\n background-color: var(--wa-color-surface-lowered);\n padding: 0.125rem 0.25rem;\n border-radius: 0.125rem;\n }\n\n .message-content pre code { background-color: transparent; padding: 0; display: block; }\n\n .code-blocwrapper {\n margin: 0.75rem 0;\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n border-radius: var(--wa-border-radius-m);\n background-color: var(--wa-color-surface-lowered);\n overflow: hidden;\n }\n\n .code-blocheader {\n display: flex;\n justify-content: flex-end;\n align-items: center;\n padding: 0.375rem 0.5rem;\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n background-color: var(--wa-color-surface-default);\n }\n\n .code-bloccontent { padding: 0.75rem; overflow-x: auto; }\n .code-bloccontent pre { margin: 0; background-color: transparent; }\n .code-bloccontent code { background-color: transparent; padding: 0; }\n\n .streaming-cursor {\n display: inline-block;\n animation: blink 1s infinite;\n color: var(--wa-color-brand-50);\n }\n\n @keyframes blink {\n 0%, 50% { opacity: 1; }\n 51%, 100% { opacity: 0; }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-chat-message': AIChatMessage;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, query } from 'lit/decorators.js';\nimport { when } from 'lit/directives/when.js';\n\n@customElement('lyra-ai-chat-input')\nexport class AIChatInput extends LitElement {\n @property({ type: String }) public value = '';\n @property({ type: Boolean }) public disabled = false;\n @property({ type: Boolean }) public busy = false;\n @property({ type: Boolean }) public hasProvider = true;\n\n @query('wa-textarea') private textareaElement?: any;\n\n private onInput(event: Event) {\n this.value = (event.target as any).value;\n this.dispatchEvent(new CustomEvent('input-change', { detail: { value: this.value }, bubbles: true, composed: true }));\n }\n\n private onKeyDown(event: KeyboardEvent) {\n if (event.key === 'Enter' && !event.shiftKey) {\n event.preventDefault();\n this.send();\n }\n }\n\n private async send() {\n if (!this.value.trim() || this.disabled || !this.hasProvider) return;\n const messageValue = this.value;\n this.value = '';\n this.requestUpdate();\n await this.updateComplete;\n if (this.textareaElement) {\n this.textareaElement.value = '';\n this.textareaElement.focus();\n }\n this.dispatchEvent(new CustomEvent('send', { detail: { value: messageValue }, bubbles: true, composed: true }));\n }\n\n private cancel() {\n this.dispatchEvent(new CustomEvent('cancel', { bubbles: true, composed: true }));\n }\n\n render() {\n return html`\n <div class=\"input-container\">\n <div class=\"input-row\">\n <wa-textarea\n placeholder=\"Type a message... (Enter to send, Shift+Enter for new line)\"\n size=\"small\"\n resize=\"auto\"\n rows=\"1\"\n .value=\"${this.value}\"\n ?disabled=\"${this.disabled || !this.hasProvider}\"\n @input=\"${this.onInput}\"\n @keydown=\"${this.onKeyDown}\">\n </wa-textarea>\n ${when(this.busy, () => html`\n <wa-button appearance=\"plain\" size=\"small\" @click=\"${this.cancel}\">\n <wa-icon name=\"stop\" label=\"Stop\"></wa-icon>\n </wa-button>\n `)}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; width: 100%; }\n .input-container { margin-bottom: 0.25rem; margin-left: 0.25rem; }\n .input-row { display: flex; gap: 0.5rem; align-items: flex-end; }\n wa-textarea { flex: 1; min-width: 0; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-chat-input': AIChatInput;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { when } from 'lit/directives/when.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { ChatMessage } from '../../core/types';\nimport type { AgentResponseGroup, AgentResponseInfo } from '../agent-group-manager';\nimport './ai-chat-message';\n\n@customElement('lyra-ai-agent-response-group')\nexport class AIAgentResponseGroup extends LitElement {\n @property({ type: Object, attribute: false })\n public group?: AgentResponseGroup;\n\n @property({ type: Function, attribute: false })\n public findStreamingMessage?: (role: string) => ChatMessage | undefined;\n\n private copyToClipboard(text: string) {\n navigator.clipboard.writeText(text).catch(err => console.error('Failed to copy:', err));\n }\n\n private renderStatusIcon(status: AgentResponseInfo['status']) {\n switch (status) {\n case 'streaming': return html`<wa-icon name=\"spinner\" class=\"spinning\"></wa-icon>`;\n case 'completed': return html`<wa-icon name=\"check-circle\" class=\"status-success\"></wa-icon>`;\n case 'error': return html`<wa-icon name=\"exclamation-circle\" class=\"status-error\"></wa-icon>`;\n }\n }\n\n private renderCard(agentInfo: AgentResponseInfo, message: ChatMessage | undefined) {\n if (!message) {\n return html`\n <div class=\"agent-card status-${agentInfo.status}\">\n <div class=\"agent-card-header\">\n <wa-icon name=\"${agentInfo.icon}\" label=\"${agentInfo.label}\"></wa-icon>\n <span>${agentInfo.label}</span>\n ${this.renderStatusIcon(agentInfo.status)}\n </div>\n <div class=\"agent-card-content waiting\">Waiting for response...</div>\n </div>\n `;\n }\n\n return html`\n <div class=\"agent-card status-${agentInfo.status}\">\n <div class=\"agent-card-header\">\n <wa-icon name=\"${agentInfo.icon}\" label=\"${agentInfo.label}\"></wa-icon>\n <span>${agentInfo.label}</span>\n ${this.renderStatusIcon(agentInfo.status)}\n <div class=\"agent-card-actions\">\n <wa-button variant=\"neutral\" appearance=\"plain\" size=\"small\" title=\"Copy\"\n @click=\"${() => this.copyToClipboard(message.content || '')}\">\n <wa-icon name=\"copy\" label=\"Copy\"></wa-icon>\n </wa-button>\n </div>\n </div>\n <div class=\"agent-card-content\">\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${agentInfo.status === 'streaming'}\"\n .showHeader=\"${false}\"\n .messageIndex=\"${agentInfo.messageIndex}\">\n </lyra-ai-chat-message>\n </div>\n </div>\n `;\n }\n\n render() {\n if (!this.group) return html``;\n\n const agents = Array.from(this.group.agents.values());\n const completedCount = agents.filter(a => a.status === 'completed').length;\n const streamingCount = agents.filter(a => a.status === 'streaming').length;\n const errorCount = agents.filter(a => a.status === 'error').length;\n const allDone = agents.length > 0 && completedCount + errorCount === agents.length;\n const isSingle = agents.length === 1;\n\n return html`\n <div class=\"agent-response-group\">\n ${when(!isSingle, () => html`\n <div class=\"group-header\">\n <wa-icon name=\"robot\" label=\"Multiple Agents\"></wa-icon>\n <span>Multiple Agents</span>\n <span class=\"status-badge\">\n ${when(streamingCount > 0, () => html`<span class=\"streaming\">${streamingCount} responding</span>`)}\n ${when(allDone, () => html`<span class=\"done\">All completed (${completedCount})</span>`)}\n </span>\n </div>\n `)}\n <div class=\"group-content\">\n ${repeat(agents, a => a.role, (agentInfo) => {\n const message = agentInfo.message ||\n (agentInfo.status === 'streaming' && this.findStreamingMessage\n ? this.findStreamingMessage(agentInfo.role)\n : undefined);\n return this.renderCard(agentInfo, message);\n })}\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; width: 100%; box-sizing: border-box; }\n\n .agent-response-group {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n }\n\n .group-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n background-color: var(--wa-color-surface-lowered);\n border: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n font-weight: 500;\n }\n\n .status-badge {\n display: flex;\n gap: 0.5rem;\n margin-left: auto;\n font-size: 0.875rem;\n }\n\n .streaming { color: var(--wa-color-brand-50); }\n .done { color: var(--wa-color-success-70); font-weight: 600; }\n\n .group-content {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n width: 100%;\n }\n\n .agent-card {\n display: flex;\n flex-direction: column;\n border: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n background-color: var(--wa-color-surface-default);\n }\n\n .agent-card.status-streaming { border-color: var(--wa-color-brand-border-quiet); }\n .agent-card.status-completed { border-color: var(--wa-color-success-border-quiet); }\n .agent-card.status-error { border-color: var(--wa-color-danger-border-quiet); }\n\n .agent-card-header {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n padding: 0.375rem 0.5rem;\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-surface-border);\n background-color: var(--wa-color-surface-lowered);\n font-weight: 500;\n font-size: 0.875rem;\n }\n\n .agent-card-actions { margin-left: auto; display: flex; gap: 0.25rem; }\n .agent-card-content { padding: 0.375rem; }\n .waiting { padding: 1rem; text-align: center; color: var(--wa-color-text-quiet); }\n\n .spinning { animation: spin 1s linear infinite; }\n .status-success { color: var(--wa-color-success-60); }\n .status-error { color: var(--wa-color-danger-60); }\n\n @keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-agent-response-group': AIAgentResponseGroup;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport type { ToolCall } from '../../core/types';\n\nexport interface ToolApprovalRequest {\n toolCalls: ToolCall[];\n message: string;\n}\n\nexport interface PendingApproval {\n role: string;\n request: ToolApprovalRequest;\n resolve: (approved: boolean) => void;\n alwaysAllowSelections: Map<string, boolean>;\n}\n\n@customElement('lyra-ai-tool-approval')\nexport class AIToolApproval extends LitElement {\n @property({ type: Map, attribute: false })\n public pendingApprovals = new Map<string, PendingApproval>();\n\n private approve(approvalId: string, approval: PendingApproval) {\n this.dispatchEvent(new CustomEvent('approve', {\n detail: { approvalId, approval },\n bubbles: true, composed: true\n }));\n approval.resolve(true);\n this.pendingApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private deny(approvalId: string, approval: PendingApproval) {\n approval.resolve(false);\n this.pendingApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private formatArgs(argsStr: string): string {\n let parsed: any = {};\n try { parsed = JSON.parse(argsStr); } catch { /* noop */ }\n return Object.entries(parsed).map(([k, v]) => `${k}=${JSON.stringify(v)}`).join(', ');\n }\n\n render() {\n if (this.pendingApprovals.size === 0) return html``;\n\n return html`\n <div class=\"approval-container\">\n ${Array.from(this.pendingApprovals.entries()).map(([id, approval]) => {\n const toolCalls = approval.request.toolCalls;\n const first = toolCalls[0];\n const summaryText = toolCalls.length === 1\n ? `AI wants to execute: ${first?.function.name}()`\n : `AI wants to execute ${toolCalls.length} tools`;\n\n return html`\n <wa-details class=\"approval-item\">\n <span slot=\"summary\" class=\"approval-summary\">\n <span>${summaryText}</span>\n <div class=\"approval-inline-actions\">\n <wa-button appearance=\"plain\" size=\"small\" variant=\"neutral\"\n @click=\"${(e: Event) => { e.stopPropagation(); this.deny(id, approval); }}\">\n <wa-icon name=\"xmark\" label=\"Deny\"></wa-icon>\n </wa-button>\n <wa-button appearance=\"plain\" size=\"small\" variant=\"success\"\n @click=\"${async (e: Event) => { e.stopPropagation(); this.approve(id, approval); }}\">\n <wa-icon name=\"check\" label=\"Approve\"></wa-icon>\n </wa-button>\n </div>\n </span>\n <div class=\"approval-detail\">\n <strong>${approval.role} wants to execute:</strong>\n <ul class=\"tool-list\">\n ${repeat(toolCalls, tc => tc.id, (tc) => {\n const argsStr = this.formatArgs(tc.function.arguments || '{}');\n const isSelected = approval.alwaysAllowSelections.get(tc.id) || false;\n return html`\n <li class=\"tool-item\">\n <label class=\"always-allow-label\">\n <wa-checkbox\n ?checked=\"${isSelected}\"\n @change=\"${(e: Event) => {\n approval.alwaysAllowSelections.set(tc.id, (e.target as any).checked);\n this.requestUpdate();\n }}\">\n </wa-checkbox>\n <span>Always allow</span>\n </label>\n <code>${tc.function.name}(${argsStr})</code>\n </li>\n `;\n })}\n </ul>\n </div>\n </wa-details>\n `;\n })}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .approval-container {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.75rem 1rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-warning-border-normal);\n background-color: var(--wa-color-warning-fill-quiet);\n }\n\n .approval-summary {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 1rem;\n width: 100%;\n }\n\n .approval-inline-actions { display: flex; gap: 0.5rem; flex-shrink: 0; }\n\n .approval-detail {\n display: flex;\n flex-direction: column;\n gap: 0.5rem;\n padding: 0.75rem 0;\n font-size: 0.875rem;\n }\n\n .tool-list { margin: 0.5rem 0 0 1.5rem; padding: 0; list-style: disc; }\n\n .tool-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n margin: 0.5rem 0;\n }\n\n .always-allow-label {\n display: flex;\n align-items: center;\n gap: 0.375rem;\n cursor: pointer;\n }\n\n code {\n font-family: var(--wa-font-mono);\n font-size: 0.875rem;\n padding: 0.125rem 0.25rem;\n background-color: var(--wa-color-neutral-fill-subtle);\n border-radius: var(--wa-border-radius-s);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-tool-approval': AIToolApproval;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property } from 'lit/decorators.js';\n\n@customElement('lyra-ai-empty-state')\nexport class AIEmptyState extends LitElement {\n @property({ type: String }) public message = 'No AI provider configured';\n @property({ type: String }) public hint = 'Click the settings icon to configure an AI provider';\n\n render() {\n return html`\n <div class=\"empty-state\">\n <wa-icon name=\"robot\" style=\"font-size: 3rem; opacity: 0.3;\"></wa-icon>\n <p>${this.message}</p>\n <p class=\"hint\">${this.hint}</p>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n }\n\n .empty-state {\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 2rem;\n text-align: center;\n color: var(--wa-color-text-quiet);\n }\n\n .empty-state p { margin: 0.5rem 0; }\n .hint { font-size: 0.875rem; opacity: 0.7; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-empty-state': AIEmptyState;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport type { TaskPlan, TaskStep, StepStatus } from '../core/types';\n\nconst STATUS_ICON: Record<StepStatus, string> = {\n running: 'spinner',\n completed: 'check-circle',\n failed: 'exclamation-circle',\n skipped: 'forward',\n pending: 'circle'\n};\n\nconst STATUS_COLOR: Record<StepStatus, string> = {\n running: 'var(--wa-color-brand-50)',\n completed: 'var(--wa-color-success-60)',\n failed: 'var(--wa-color-danger-60)',\n skipped: 'var(--wa-color-neutral-40)',\n pending: 'var(--wa-color-neutral-40)'\n};\n\n@customElement('lyra-ai-task-progress-panel')\nexport class AITaskProgressPanel extends LitElement {\n @property({ type: Object, attribute: false })\n public plan?: TaskPlan;\n\n @state()\n private expanded = true;\n\n render() {\n if (!this.plan) return html``;\n\n const completedCount = this.plan.steps.filter(s => s.status === 'completed').length;\n const totalCount = this.plan.steps.length;\n const progress = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0;\n\n return html`\n <div class=\"taspanel\">\n <div class=\"panel-header\" @click=\"${() => { this.expanded = !this.expanded; }}\">\n <wa-icon name=\"diagram-project\" label=\"Task Plan\"></wa-icon>\n <span class=\"panel-title\">Task Plan</span>\n <span class=\"progress-text\">${completedCount}/${totalCount}</span>\n <wa-progress-bar value=\"${progress}\" class=\"progress-bar\"></wa-progress-bar>\n <wa-icon name=\"${this.expanded ? 'chevron-up' : 'chevron-down'}\" label=\"toggle\"></wa-icon>\n </div>\n ${when(this.expanded, () => html`\n <div class=\"panel-body\">\n ${repeat(this.plan!.steps, s => s.id, (step) => html`\n <div class=\"step-row\">\n <wa-icon\n name=\"${STATUS_ICON[step.status] ?? 'circle'}\"\n style=\"color: ${STATUS_COLOR[step.status] ?? 'var(--wa-color-neutral-40)'}; ${step.status === 'running' ? 'animation: spin 1s linear infinite;' : ''}\">\n </wa-icon>\n <div class=\"step-info\">\n <span class=\"step-role\">${step.role}</span>\n <span class=\"step-task\">${step.subTask}</span>\n </div>\n ${when(step.revisions > 0, () => html`\n <span class=\"revisions-badge\">${step.revisions} rev</span>\n `)}\n </div>\n `)}\n </div>\n `)}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .taspanel {\n border: solid var(--wa-border-width-s) var(--wa-color-brand-border-quiet);\n border-radius: var(--wa-border-radius-m);\n background: var(--wa-color-surface-default);\n margin: 0.5rem 0;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n user-select: none;\n }\n\n .panel-title {\n font-weight: 500;\n flex: 0 0 auto;\n }\n\n .progress-text {\n font-size: 0.8rem;\n color: var(--wa-color-text-quiet);\n }\n\n .progress-bar {\n flex: 1;\n min-width: 60px;\n }\n\n .panel-body {\n display: flex;\n flex-direction: column;\n gap: 0.25rem;\n padding: 0.5rem 0.75rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .step-row {\n display: flex;\n align-items: flex-start;\n gap: 0.5rem;\n padding: 0.25rem 0;\n }\n\n .step-info {\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n flex: 1;\n min-width: 0;\n }\n\n .step-role {\n font-size: 0.75rem;\n font-weight: 600;\n color: var(--wa-color-text-quiet);\n text-transform: uppercase;\n }\n\n .step-task {\n font-size: 0.85rem;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .revisions-badge {\n font-size: 0.7rem;\n padding: 0.1rem 0.3rem;\n background: var(--wa-color-warning-fill-quiet);\n border-radius: var(--wa-border-radius-s);\n color: var(--wa-color-warning-70);\n flex-shrink: 0;\n }\n\n @keyframes spin {\n from { transform: rotate(0deg); }\n to { transform: rotate(360deg); }\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-task-progress-panel': AITaskProgressPanel;\n }\n}\n","import { css, html, LitElement } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport type { Artifact, ArtifactType } from '../core/types';\n\nconst ARTIFACT_TYPE_ICON: Record<ArtifactType, string> = {\n code: 'code',\n json: 'brackets-curly',\n 'file-list': 'list',\n plan: 'diagram-project',\n review: 'magnifying-glass',\n text: 'file-lines'\n};\n\n@customElement('lyra-ai-workspace-panel')\nexport class AIWorkspacePanel extends LitElement {\n @property({ type: Array, attribute: false })\n public artifacts: Artifact[] = [];\n\n @state()\n private expanded = false;\n\n @state()\n private selectedArtifact?: Artifact;\n\n render() {\n if (this.artifacts.length === 0) return html``;\n\n return html`\n <div class=\"workspace-panel\">\n <div class=\"panel-header\" @click=\"${() => { this.expanded = !this.expanded; this.selectedArtifact = undefined; }}\">\n <wa-icon name=\"folder-open\" label=\"Workspace\"></wa-icon>\n <span class=\"panel-title\">Workspace</span>\n <span class=\"count-badge\">${this.artifacts.length} artifact${this.artifacts.length !== 1 ? 's' : ''}</span>\n <wa-icon name=\"${this.expanded ? 'chevron-up' : 'chevron-down'}\" label=\"toggle\"></wa-icon>\n </div>\n ${when(this.expanded, () => html`\n <div class=\"panel-body\">\n <div class=\"artifact-list\">\n ${repeat(this.artifacts, a => a.id, (artifact) => html`\n <div\n class=\"artifact-item ${this.selectedArtifact?.id === artifact.id ? 'selected' : ''}\"\n @click=\"${() => { this.selectedArtifact = this.selectedArtifact?.id === artifact.id ? undefined : artifact; }}\">\n <wa-icon name=\"${ARTIFACT_TYPE_ICON[artifact.type] ?? 'file-lines'}\" label=\"${artifact.type}\"></wa-icon>\n <div class=\"artifact-meta\">\n <span class=\"artifact-id\">${artifact.id}</span>\n <span class=\"artifact-producer\">by ${artifact.producedBy}</span>\n </div>\n <span class=\"artifact-type\">${artifact.type}</span>\n </div>\n ${when(this.selectedArtifact?.id === artifact.id, () => html`\n <div class=\"artifact-content\">\n <pre>${artifact.content}</pre>\n </div>\n `)}\n `)}\n </div>\n </div>\n `)}\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; }\n\n .workspace-panel {\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n border-radius: var(--wa-border-radius-m);\n background: var(--wa-color-surface-default);\n margin: 0.5rem 0;\n }\n\n .panel-header {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n cursor: pointer;\n user-select: none;\n }\n\n .panel-title { font-weight: 500; }\n\n .count-badge {\n font-size: 0.8rem;\n color: var(--wa-color-text-quiet);\n margin-left: auto;\n }\n\n .panel-body {\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .artifact-list { display: flex; flex-direction: column; }\n\n .artifact-item {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.4rem 0.75rem;\n cursor: pointer;\n }\n\n .artifact-item:hover { background: var(--wa-color-surface-lowered); }\n .artifact-item.selected { background: var(--wa-color-brand-fill-quiet); }\n\n .artifact-meta {\n display: flex;\n flex-direction: column;\n flex: 1;\n min-width: 0;\n }\n\n .artifact-id {\n font-size: 0.85rem;\n font-weight: 500;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .artifact-producer {\n font-size: 0.75rem;\n color: var(--wa-color-text-quiet);\n }\n\n .artifact-type {\n font-size: 0.75rem;\n padding: 0.1rem 0.3rem;\n background: var(--wa-color-surface-lowered);\n border-radius: var(--wa-border-radius-s);\n }\n\n .artifact-content {\n padding: 0.5rem 0.75rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n background: var(--wa-color-surface-lowered);\n }\n\n .artifact-content pre {\n margin: 0;\n white-space: pre-wrap;\n word-break: breaword;\n font-size: 0.8rem;\n max-height: 200px;\n overflow-y: auto;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-workspace-panel': AIWorkspacePanel;\n }\n}\n","import { css, html, nothing, TemplateResult } from 'lit';\nimport { customElement, state } from 'lit/decorators.js';\nimport { LyraPart } from '@eclipse-lyra/core';\nimport { when } from 'lit/directives/when.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { commandRegistry as globalCommandRegistry } from '@eclipse-lyra/core';\nimport { taskService, uiContext, appSettings } from '@eclipse-lyra/core';\nimport { toastError } from '@eclipse-lyra/core';\n\nimport type { ChatMessage, ChatHistory, ChatProvider, TaskPlan, Artifact } from '../core/types';\nimport { TOPIC_AICONFIG_CHANGED, KEY_AI_CONFIG } from '../core/constants';\nimport { aiService } from '../service/ai-service';\n\nimport { SessionManager } from './session-manager';\nimport { StreamManager } from './stream-manager';\nimport { ProviderManager } from './provider-manager';\nimport { AgentGroupManager } from './agent-group-manager';\n\nimport './components/ai-chat-message';\nimport './components/ai-chat-input';\nimport './components/ai-agent-response-group';\nimport './components/ai-tool-approval';\nimport './components/ai-empty-state';\nimport './task-progress-panel';\nimport './workspace-panel';\nimport type { PendingApproval } from './components/ai-tool-approval';\n\n@customElement('lyra-aiview')\nexport class LyraAIView extends LyraPart {\n private sessionManager = new SessionManager();\n private scrollDebounceTimer?: ReturnType<typeof setTimeout>;\n\n private streamManager = new StreamManager(() => {\n this.requestUpdate();\n if (this.scrollDebounceTimer) clearTimeout(this.scrollDebounceTimer);\n this.scrollDebounceTimer = setTimeout(async () => {\n await this.updateComplete;\n this.scrollToBottom();\n this.scrollDebounceTimer = undefined;\n }, 100);\n });\n\n private providerManager = new ProviderManager(aiService);\n private agentGroupManager = new AgentGroupManager();\n\n @state() private busy = false;\n @state() private inputValue = '';\n @state() private requireToolApproval = true;\n @state() private showHistory = false;\n @state() private currentTaskPlan?: TaskPlan;\n @state() private currentArtifacts: Artifact[] = [];\n @state() private pendingToolApprovals = new Map<string, PendingApproval>();\n\n private toolApprovalAllowlist = new Set<string>();\n private abortController?: AbortController;\n\n protected async doBeforeUI() {\n this.subscribe(TOPIC_AICONFIG_CHANGED, () => this.onAIConfigChanged());\n await this.sessionManager.load();\n if (!this.sessionManager.getActiveSession()) {\n this.sessionManager.createSession();\n }\n await this.providerManager.initialize();\n await this.loadSettings();\n this.requestUpdate();\n }\n\n private async onAIConfigChanged() {\n await this.providerManager.initialize();\n await this.loadSettings();\n this.requestUpdate();\n }\n\n private async loadSettings() {\n const config = await appSettings.get(KEY_AI_CONFIG) as any || {};\n this.requireToolApproval = config.requireToolApproval !== false;\n const allowlist = await this.providerManager.loadToolApprovalAllowlist();\n this.toolApprovalAllowlist = new Set(allowlist);\n }\n\n private async scrollToBottom() {\n await this.updateComplete;\n const scroller = this.shadowRoot?.querySelector('wa-scroller.chat-messages') as any;\n if (!scroller) return;\n const container = scroller.shadowRoot?.querySelector('.scroll-container') as HTMLElement;\n if (container) {\n container.scrollTop = container.scrollHeight;\n } else if (scroller.scrollTo) {\n scroller.scrollTo({ top: scroller.scrollHeight, behavior: 'smooth' });\n }\n }\n\n private resetViewState() {\n this.inputValue = '';\n this.showHistory = false;\n this.currentTaskPlan = undefined;\n this.currentArtifacts = [];\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private createNewSession() {\n this.sessionManager.createSession();\n this.resetViewState();\n }\n\n private switchToSession(sessionId: string) {\n if (!this.sessionManager.switchToSession(sessionId)) return;\n this.resetViewState();\n }\n\n private deletePastSession(sessionId: string) {\n this.sessionManager.deletePastSession(sessionId);\n this.requestUpdate();\n this.updateToolbar();\n }\n\n private async sendMessage() {\n const prompt = this.inputValue.trim();\n if (!prompt || this.busy) return;\n this.inputValue = '';\n await this.handlePrompt(prompt);\n }\n\n private async handleResend(message: ChatMessage) {\n if (!message || message.role !== 'user') return;\n await this.handlePrompt(message.content);\n }\n\n private cancelStream() {\n this.abortController?.abort();\n this.abortController = undefined;\n this.busy = false;\n this.streamManager.cancelUpdates();\n }\n\n public async handlePrompt(prompt: string): Promise<void> {\n if (prompt.startsWith('/')) {\n await this.runCommand(prompt.substring(1));\n return;\n }\n\n const selectedProvider = this.providerManager.getSelectedProvider();\n if (!selectedProvider) {\n toastError('Please configure an AI provider in settings');\n return;\n }\n\n const session = this.sessionManager.getActiveSession();\n if (!session) return;\n\n const message = aiService.createMessage(prompt);\n this.sessionManager.addMessage(message);\n\n if (session.history.length === 1) {\n this.sessionManager.setTitle(this.sessionManager.generateTitle(prompt));\n this.updateToolbar();\n }\n\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n this.busy = true;\n this.currentTaskPlan = undefined;\n this.currentArtifacts = [];\n\n this.abortController = new AbortController();\n const streamingAgents = new Map<string, number>();\n const chatContext: ChatHistory = { history: [...session.history] };\n const sessionId = session.id;\n\n const execContext = globalCommandRegistry.createExecutionContext();\n const callContext = uiContext.createChild({ ...execContext });\n const contributions = aiService.getAgentContributions();\n\n if (contributions.length === 0) {\n toastError('No agents are registered.');\n this.busy = false;\n return;\n }\n\n const matchingAgents = contributions.filter(c =>\n !c.canHandle || c.canHandle({ ...callContext.getProxy(), userPrompt: prompt })\n ).sort((a, b) => (b.priority || 0) - (a.priority || 0));\n\n if (matchingAgents.length === 0) {\n toastError(`No agents available. Available: ${contributions.map(c => c.role).join(', ')}`);\n this.busy = false;\n return;\n }\n\n const roles = matchingAgents.map(a => a.role);\n const currentSession = this.sessionManager.getActiveSession();\n if (!currentSession) return;\n\n const groupId = this.agentGroupManager.createGroup(\n sessionId,\n currentSession.history.length - 1,\n message,\n roles,\n (role: string) => {\n const contrib = contributions.find(c => c.role === role);\n return { label: (contrib as any)?.label || role, icon: (contrib as any)?.icon || 'robot' };\n }\n );\n\n taskService.runAsync('Calling AI assistant', async () => {\n return aiService.executeAgentWorkflow({\n chatContext,\n chatConfig: selectedProvider,\n callContext,\n execution: 'parallel',\n stream: true,\n signal: this.abortController!.signal,\n roles,\n requireToolApproval: this.requireToolApproval,\n onToolApprovalRequest: async (role: string, request: any): Promise<boolean> => {\n const allAllowed = request.toolCalls.every((tc: any) => this.toolApprovalAllowlist.has(tc.function.name));\n if (allAllowed) return true;\n\n return new Promise<boolean>((resolve) => {\n const approvalId = `approval-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n const pending: PendingApproval = {\n role,\n request,\n resolve,\n alwaysAllowSelections: new Map()\n };\n this.pendingToolApprovals.set(approvalId, pending);\n this.requestUpdate();\n });\n },\n onAgentStart: async (role: string) => {\n const streamIndex = this.streamManager.createStreamingMessage(role);\n streamingAgents.set(role, streamIndex);\n this.agentGroupManager.updateAgentStatus(groupId, role, 'streaming');\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n },\n onToken: (role: string, token: string) => {\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) this.streamManager.updateStreamingMessage(streamIndex, token);\n },\n onAgentComplete: async (role: string, completedMessage: ChatMessage) => {\n const targetSession = this.sessionManager.getActiveSession();\n if (!targetSession || targetSession.id !== sessionId) return;\n\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) {\n this.streamManager.completeStreamingMessage(streamIndex, completedMessage);\n const messageIndex = targetSession.history.length;\n this.sessionManager.addMessage(completedMessage);\n streamingAgents.delete(role);\n this.streamManager.removeStreamingMessage(streamIndex);\n this.agentGroupManager.updateAgentStatus(groupId, role, 'completed', completedMessage, messageIndex);\n this.requestUpdate();\n await this.updateComplete;\n this.scrollToBottom();\n }\n },\n onAgentError: (role: string, error: Error) => {\n const streamIndex = streamingAgents.get(role);\n if (streamIndex !== undefined) {\n this.streamManager.removeStreamingMessage(streamIndex);\n streamingAgents.delete(role);\n }\n this.agentGroupManager.updateAgentStatus(groupId, role, 'error', { role, content: `Error: ${error.message}` });\n this.requestUpdate();\n toastError(`Agent ${role} error: ${error.message}`);\n }\n }).then(() => { this.agentGroupManager.clearCurrentGroup(); });\n }).catch((error: any) => {\n if (error?.name !== 'AbortError') toastError(`${error}`);\n }).finally(async () => {\n this.busy = false;\n this.abortController = undefined;\n this.streamManager.reset();\n this.agentGroupManager.clearCurrentGroup();\n this.requestUpdate();\n this.updateToolbar();\n });\n }\n\n private async runCommand(prompt: string) {\n const splits = prompt.trim().split(/\\s+/);\n if (splits.length === 0) return;\n const commandId = splits.shift()!;\n const command = globalCommandRegistry.getCommand(commandId);\n if (!command) { toastError(`Command not found: ${commandId}`); return; }\n const params: Record<string, string> = {};\n splits.forEach((c, i) => {\n if (command.parameters?.[i]) params[command.parameters[i].name] = c;\n });\n await globalCommandRegistry.execute(commandId, globalCommandRegistry.createExecutionContext(params));\n this.requestUpdate();\n }\n\n private handleToolApproval(e: CustomEvent) {\n const { approvalId, approval } = e.detail;\n const alwaysAllowed = Array.from((approval.alwaysAllowSelections as Map<string, boolean>).entries())\n .filter(([, v]) => v)\n .map(([k]) => k);\n alwaysAllowed.forEach(name => this.toolApprovalAllowlist.add(name));\n this.pendingToolApprovals.delete(approvalId);\n this.requestUpdate();\n }\n\n private renderMessage(message: ChatMessage, index: number, isStreaming = false): TemplateResult {\n return html`\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${isStreaming}\"\n .showHeader=\"${true}\"\n .messageIndex=\"${index}\"\n @resend=\"${(e: CustomEvent) => this.handleResend(e.detail.message)}\">\n </lyra-ai-chat-message>\n `;\n }\n\n protected renderToolbar() {\n const past = this.sessionManager.getPastSessions();\n const session = this.sessionManager.getActiveSession();\n\n return html`\n <span style=\"flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:0.875rem;font-weight:500;padding:0 0.25rem;\">${session?.title || 'New Chat'}</span>\n <wa-button appearance=\"plain\" size=\"small\" title=\"New chat\"\n @click=\"${() => this.createNewSession()}\">\n <wa-icon name=\"plus\" label=\"New chat\"></wa-icon>\n </wa-button>\n ${past.length > 0 ? html`\n <wa-dropdown\n ?open=\"${this.showHistory}\"\n @wa-after-hide=\"${() => { this.showHistory = false; }}\"\n placement=\"bottom-start\">\n <wa-button slot=\"trigger\" appearance=\"plain\" size=\"small\" with-caret\n title=\"Chat history\"\n @click=\"${() => { this.showHistory = !this.showHistory; }}\">\n <wa-icon name=\"clock-rotate-left\" label=\"History\"></wa-icon>\n </wa-button>\n ${past.map(s => html`\n <wa-dropdown-item @click=\"${() => this.switchToSession(s.id)}\">\n <wa-icon name=\"message\" label=\"Session\" slot=\"icon\"></wa-icon>\n <span style=\"flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\">${s.title || 'Unnamed Chat'}</span>\n <wa-button slot=\"details\" appearance=\"plain\" size=\"small\" title=\"Delete\"\n @click=\"${(e: Event) => { e.stopPropagation(); this.deletePastSession(s.id); }}\">\n <wa-icon name=\"trash\" label=\"Delete\"></wa-icon>\n </wa-button>\n </wa-dropdown-item>\n `)}\n </wa-dropdown>\n ` : nothing}\n <lyra-command cmd=\"open_ai_config\" icon=\"gear\" title=\"AI Settings\"></lyra-command>\n `;\n }\n\n render() {\n const session = this.sessionManager.getActiveSession();\n const selectedProvider = this.providerManager.getSelectedProvider();\n\n return html`\n <div class=\"chat-container\">\n <wa-scroller class=\"chat-messages\" orientation=\"vertical\">\n <div class=\"chat-content\">\n ${when(!selectedProvider, () => html`\n <lyra-ai-empty-state\n message=\"No AI provider configured\"\n hint='Click the settings icon below to configure an AI provider'>\n </lyra-ai-empty-state>\n `, () => when(!session || session.history.length === 0, () => html`\n <lyra-ai-empty-state message=\"How can I help you?\" hint=\"\"></lyra-ai-empty-state>\n `, () => html`\n ${session!.history.map((message: ChatMessage, idx: number) => {\n const group = this.agentGroupManager.findGroupForUserMessage(session!.id, idx, message);\n if (group && message.role === 'user') {\n return html`\n <lyra-ai-chat-message\n .message=\"${message}\"\n .isStreaming=\"${false}\"\n .showHeader=\"${true}\"\n .messageIndex=\"${idx}\"\n @resend=\"${(e: CustomEvent) => this.handleResend(e.detail.message)}\">\n </lyra-ai-chat-message>\n <lyra-ai-agent-response-group\n .group=\"${group}\"\n .findStreamingMessage=\"${(role: string) => this.streamManager.findStreamingMessage(role)}\">\n </lyra-ai-agent-response-group>\n `;\n }\n\n if (this.agentGroupManager.findGroupForMessage(session!.id, message.role, idx)) {\n return html``;\n }\n\n return this.renderMessage(message, idx);\n })}\n\n ${this.streamManager.getAllStreamingMessages()\n .filter(m => !this.agentGroupManager.getAllGroups()\n .some(g => g.sessionId === session!.id && g.agents.has(m.message.role)))\n .map(m => this.renderMessage(m.message, -1, m.isStreaming))}\n\n ${when(this.busy && this.streamManager.getAllStreamingMessages().length === 0, () => html`\n <div class=\"thinking-indicator\">\n <wa-progress-ring indeterminate size=\"small\"></wa-progress-ring>\n <span>Thinking…</span>\n </div>\n `)}\n `))}\n\n ${when(this.currentTaskPlan, () => html`\n <lyra-ai-task-progress-panel .plan=\"${this.currentTaskPlan}\"></lyra-ai-task-progress-panel>\n `)}\n\n ${when(this.currentArtifacts.length > 0, () => html`\n <lyra-ai-workspace-panel .artifacts=\"${this.currentArtifacts}\"></lyra-ai-workspace-panel>\n `)}\n </div>\n </wa-scroller>\n\n ${when(this.pendingToolApprovals.size > 0, () => html`\n <lyra-ai-tool-approval\n .pendingApprovals=\"${this.pendingToolApprovals}\"\n @approve=\"${(e: CustomEvent) => this.handleToolApproval(e)}\">\n </lyra-ai-tool-approval>\n `)}\n\n <div class=\"input-area\">\n <lyra-ai-chat-input\n .value=\"${this.inputValue}\"\n .busy=\"${this.busy}\"\n .disabled=\"${!selectedProvider}\"\n .hasProvider=\"${!!selectedProvider}\"\n @input-change=\"${(e: CustomEvent) => { this.inputValue = e.detail.value; }}\"\n @send=\"${(e: CustomEvent) => { this.inputValue = e.detail.value; this.sendMessage(); }}\"\n @cancel=\"${() => this.cancelStream()}\">\n </lyra-ai-chat-input>\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n background: var(--wa-color-surface-default);\n }\n\n .chat-container {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n }\n\n .chat-messages {\n flex: 1;\n overflow: hidden;\n }\n\n .chat-content {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 1rem;\n min-height: 100%;\n box-sizing: border-box;\n }\n\n .thinking-indicator {\n display: flex;\n align-items: center;\n gap: 0.5rem;\n padding: 0.5rem 0.75rem;\n color: var(--wa-color-text-quiet);\n font-size: 0.875rem;\n }\n\n .input-area {\n padding: 0.5rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n flex-shrink: 0;\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-aiview': LyraAIView;\n }\n}\n","import { css, html } from 'lit';\nimport { customElement } from 'lit/decorators.js';\nimport { LyraElement } from '@eclipse-lyra/core';\nimport { subscribe, confirmDialog } from '@eclipse-lyra/core';\nimport { tokenUsageTracker, EMPTY_USAGE } from '../service/token-usage-tracker';\nimport { TOPIC_AI_STREAM_COMPLETE } from '../core/constants';\nimport type { ProviderTokenUsage } from '../core/types';\n\n@customElement('lyra-token-usage')\nexport class LyraTokenUsage extends LyraElement {\n private totalUsage: ProviderTokenUsage = { ...EMPTY_USAGE };\n private providerUsage: Record<string, ProviderTokenUsage> = {};\n\n connectedCallback() {\n super.connectedCallback();\n this.loadUsage();\n subscribe(TOPIC_AI_STREAM_COMPLETE, () => { this.loadUsage(); });\n }\n\n private async loadUsage() {\n this.totalUsage = await tokenUsageTracker.getTotalUsage();\n this.providerUsage = await tokenUsageTracker.getAllProviderUsage();\n this.requestUpdate();\n }\n\n private formatNumber(num: number): string {\n if (num >= 1_000_000) return (num / 1_000_000).toFixed(2) + 'M';\n if (num >= 1_000) return (num / 1_000).toFixed(1) + 'K';\n return num.toString();\n }\n\n private async handleReset() {\n if (await confirmDialog('Reset all token usage statistics?')) {\n await tokenUsageTracker.reset();\n await this.loadUsage();\n }\n }\n\n private renderStatItem(label: string, value: number) {\n return html`\n <div class=\"stat-item\">\n <span class=\"stat-label\">${label}</span>\n <span class=\"stat-value\">${this.formatNumber(value)}</span>\n </div>\n `;\n }\n\n protected render() {\n if (this.totalUsage.totalTokens === 0) return html``;\n\n return html`\n <wa-dropdown placement=\"top-end\" distance=\"8\">\n <wa-button slot=\"trigger\" appearance=\"plain\" size=\"small\" title=\"Token usage\">\n <wa-icon name=\"database\" label=\"Tokens\" slot=\"start\"></wa-icon>\n ${this.formatNumber(this.totalUsage.totalTokens)} tokens\n </wa-button>\n\n <h3>Token Usage</h3>\n\n <h6>Total</h6>\n <wa-dropdown-item>\n <span>All providers</span>\n <div class=\"stats-row\">\n ${this.renderStatItem('Prompt', this.totalUsage.promptTokens)}\n ${this.renderStatItem('Completion', this.totalUsage.completionTokens)}\n ${this.renderStatItem('Total', this.totalUsage.totalTokens)}\n ${this.renderStatItem('Requests', this.totalUsage.requestCount)}\n </div>\n </wa-dropdown-item>\n\n ${Object.keys(this.providerUsage).length > 0 ? html`\n <wa-divider></wa-divider>\n <h6>By Provider</h6>\n ${Object.entries(this.providerUsage).map(([name, usage]) => html`\n <wa-dropdown-item>\n <span class=\"provider-name\">${name}</span>\n <div class=\"stats-row\">\n ${this.renderStatItem('Prompt', usage.promptTokens)}\n ${this.renderStatItem('Completion', usage.completionTokens)}\n ${this.renderStatItem('Total', usage.totalTokens)}\n ${this.renderStatItem('Req', usage.requestCount)}\n </div>\n </wa-dropdown-item>\n `)}\n ` : ''}\n\n <wa-divider></wa-divider>\n <wa-dropdown-item variant=\"danger\" @click=\"${() => this.handleReset()}\">\n <wa-icon name=\"trash\" slot=\"icon\"></wa-icon>\n Reset statistics\n </wa-dropdown-item>\n </wa-dropdown>\n `;\n }\n\n static styles = css`\n :host { display: inline-block; }\n\n wa-dropdown::part(menu) { min-width: 320px; max-width: 420px; }\n\n h3 {\n padding: var(--wa-space-s) var(--wa-space-m);\n margin: 0;\n font-weight: 600;\n font-size: 0.95em;\n }\n\n h6 {\n padding: var(--wa-space-xs) var(--wa-space-m);\n margin: 0;\n font-weight: 600;\n font-size: 0.85em;\n color: var(--wa-color-neutral-text-subtle);\n text-transform: uppercase;\n letter-spacing: 0.05em;\n }\n\n .provider-name { font-weight: 500; }\n\n .stats-row { display: flex; gap: var(--wa-space-m); font-size: 0.875rem; }\n\n .stat-item {\n display: flex;\n flex-direction: column;\n align-items: flex-end;\n }\n\n .stat-label { font-size: 0.8em; color: var(--wa-color-neutral-text-subtle); }\n .stat-value { font-weight: 600; }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-token-usage': LyraTokenUsage;\n }\n}\n","import { css, html } from 'lit';\nimport { customElement, property, state } from 'lit/decorators.js';\nimport { repeat } from 'lit/directives/repeat.js';\nimport { when } from 'lit/directives/when.js';\nimport { LyraPart } from '@eclipse-lyra/core';\nimport { EditorInput } from '@eclipse-lyra/core';\nimport { appSettings, TOPIC_SETTINGS_CHANGED } from '@eclipse-lyra/core';\nimport { KEY_AI_CONFIG, TOPIC_AICONFIG_CHANGED, CID_CHAT_PROVIDERS } from '../../core/constants';\nimport { subscribe } from '@eclipse-lyra/core';\nimport { confirmDialog } from '@eclipse-lyra/core';\nimport { contributionRegistry } from '@eclipse-lyra/core';\nimport { ProviderFactory } from '../../providers/provider-factory';\nimport type { AIConfig, ChatProvider } from '../../core/types';\nimport type { ChatProviderContribution } from '../../core/interfaces';\n\n@customElement('lyra-ai-config-editor')\nexport class LyraAIConfigEditor extends LyraPart {\n @property({ attribute: false }) public input?: EditorInput;\n\n @state() private providers: ChatProvider[] = [];\n @state() private defaultProvider = '';\n @state() private hasChanges = false;\n @state() private availableModels: Array<{ id: string; name?: string }> = [];\n @state() private loadingModels = false;\n @state() private requireToolApproval = true;\n @state() private smartToolDetection = false;\n\n // Editing state for each provider field\n @state() private editingState: Record<number, Partial<ChatProvider>> = {};\n\n private aiConfig?: AIConfig;\n private providerFactory = new ProviderFactory();\n\n protected async doInitUI() {\n await this.loadConfig();\n subscribe(TOPIC_AICONFIG_CHANGED, () => this.loadConfig());\n subscribe(TOPIC_SETTINGS_CHANGED, () => this.loadConfig());\n }\n\n private async loadConfig() {\n const config = await appSettings.get(KEY_AI_CONFIG) as AIConfig | undefined;\n this.aiConfig = config;\n\n const contributed = (contributionRegistry.getContributions(CID_CHAT_PROVIDERS) as ChatProviderContribution[]).map(c => c.provider);\n const configProviders = config?.providers || [];\n const existingNames = new Set(configProviders.map(p => p.name));\n this.providers = [...configProviders, ...contributed.filter(p => !existingNames.has(p.name))];\n\n this.defaultProvider = config?.defaultProvider || '';\n this.requireToolApproval = config?.requireToolApproval !== false;\n this.smartToolDetection = config?.smartToolDetection !== undefined ? config.smartToolDetection : false;\n this.editingState = {};\n this.hasChanges = false;\n this.markDirty(false);\n }\n\n private getEditValue(index: number, field: keyof ChatProvider): string {\n const editing = this.editingState[index];\n if (editing && field in editing) return (editing as any)[field] ?? '';\n const provider = this.providers[index];\n return provider ? ((provider as any)[field] ?? '') : '';\n }\n\n private setEditValue(index: number, field: keyof ChatProvider, value: string) {\n this.editingState = {\n ...this.editingState,\n [index]: { ...(this.editingState[index] || {}), [field]: value }\n };\n this.providers = this.providers.map((p, i) =>\n i === index ? { ...p, [field]: value } : p\n );\n this.markDirtyAndUpdate();\n }\n\n private markDirtyAndUpdate() {\n this.hasChanges = true;\n this.markDirty(true);\n }\n\n private async fetchModels(index: number): Promise<void> {\n const provider = this.providers[index];\n if (!provider) return;\n this.loadingModels = true;\n this.availableModels = [];\n try {\n const instance = this.providerFactory.getProvider(provider);\n if (instance.getAvailableModels) {\n const models = await instance.getAvailableModels(provider);\n this.availableModels = Array.isArray(models) ? models : [];\n }\n } finally {\n this.loadingModels = false;\n }\n }\n\n private async saveConfig() {\n const updatedConfig: AIConfig = {\n ...(this.aiConfig ?? {}),\n defaultProvider: this.defaultProvider,\n providers: this.providers,\n requireToolApproval: this.requireToolApproval,\n smartToolDetection: this.smartToolDetection\n };\n await appSettings.set(KEY_AI_CONFIG, updatedConfig);\n this.aiConfig = updatedConfig;\n this.hasChanges = false;\n this.markDirty(false);\n }\n\n async save() {\n if (!this.hasChanges) return;\n await this.saveConfig();\n }\n\n private addProvider() {\n this.providers = [...this.providers, { name: 'new-provider', model: '', apiKey: '', chatApiEndpoint: '' }];\n this.markDirtyAndUpdate();\n }\n\n private async deleteProvider(index: number) {\n const provider = this.providers[index];\n if (!await confirmDialog(`Delete provider \"${provider.name}\"?`)) return;\n if (this.defaultProvider === provider.name) this.defaultProvider = '';\n this.providers = this.providers.filter((_, i) => i !== index);\n this.markDirtyAndUpdate();\n }\n\n private renderProviderField(index: number, field: keyof ChatProvider, type: 'text' | 'password' = 'text') {\n const value = this.getEditValue(index, field);\n return html`\n <wa-input\n type=\"${type}\"\n ?password-toggle=\"${type === 'password'}\"\n .value=\"${value}\"\n @input=\"${(e: Event) => this.setEditValue(index, field, (e.target as any).value)}\">\n </wa-input>\n `;\n }\n\n render() {\n return html`\n <div class=\"editor\">\n <div class=\"editor-header\">\n <h2>AI Providers</h2>\n <wa-button variant=\"brand\" appearance=\"filled\" @click=\"${this.addProvider}\">\n Add Provider\n </wa-button>\n </div>\n\n ${when(this.providers.length === 0, () => html`\n <div class=\"empty-state\"><p>No providers configured.</p></div>\n `, () => html`\n <div class=\"providers-list\">\n ${repeat(this.providers, (_, i) => i, (provider, index) => html`\n <div class=\"provider-card\">\n <div class=\"provider-card-header ${this.defaultProvider === provider.name ? 'is-default' : ''}\">\n <span class=\"provider-name\">${provider.name}</span>\n ${this.defaultProvider === provider.name\n ? html`<span class=\"default-badge\">Default</span>`\n : html`<wa-button appearance=\"plain\" size=\"small\" title=\"Set as default\"\n @click=\"${() => { this.defaultProvider = provider.name; this.markDirtyAndUpdate(); }}\">\n Set default\n </wa-button>`\n }\n <wa-button variant=\"danger\" appearance=\"plain\" size=\"small\"\n @click=\"${() => this.deleteProvider(index)}\">\n Delete\n </wa-button>\n </div>\n <div class=\"provider-fields\">\n <div class=\"field-row\">\n <label>Name</label>\n ${this.renderProviderField(index, 'name')}\n </div>\n <div class=\"field-row\">\n <label>Model</label>\n <div class=\"model-row\">\n ${this.renderProviderField(index, 'model')}\n <wa-button appearance=\"plain\" size=\"small\"\n @click=\"${async () => { await this.fetchModels(index); }}\"\n title=\"Fetch available models\">\n <wa-icon name=\"refresh\" label=\"Refresh\"></wa-icon>\n </wa-button>\n </div>\n ${when(this.loadingModels, () => html`\n <wa-progress-ring indeterminate size=\"small\"></wa-progress-ring>\n `)}\n ${when(this.availableModels.length > 0, () => html`\n <wa-dropdown\n @wa-select=\"${(e: CustomEvent) => {\n if (e.detail.item?.value) this.setEditValue(index, 'model', e.detail.item.value);\n }}\">\n <wa-button slot=\"trigger\" size=\"small\" appearance=\"plain\" with-caret>\n Select model\n </wa-button>\n ${this.availableModels.map(m => html`\n <wa-dropdown-item value=\"${m.id}\">${m.name || m.id}</wa-dropdown-item>\n `)}\n </wa-dropdown>\n `)}\n </div>\n <div class=\"field-row\">\n <label>API Endpoint</label>\n ${this.renderProviderField(index, 'chatApiEndpoint')}\n </div>\n <div class=\"field-row\">\n <label>API Key</label>\n ${this.renderProviderField(index, 'apiKey', 'password')}\n </div>\n </div>\n </div>\n `)}\n </div>\n `)}\n\n <div class=\"settings-section\">\n <h3>Tool Settings</h3>\n <wa-checkbox\n ?checked=\"${this.requireToolApproval}\"\n @change=\"${(e: Event) => { this.requireToolApproval = (e.target as any).checked; this.markDirtyAndUpdate(); }}\">\n Require approval before executing tools\n </wa-checkbox>\n <wa-checkbox\n ?checked=\"${this.smartToolDetection}\"\n @change=\"${(e: Event) => { this.smartToolDetection = (e.target as any).checked; this.markDirtyAndUpdate(); }}\">\n Smart tool detection (use ML to detect when tools are needed)\n </wa-checkbox>\n </div>\n </div>\n `;\n }\n\n static styles = css`\n :host { display: block; height: 100%; overflow: auto; }\n\n .editor {\n display: flex;\n flex-direction: column;\n gap: 1.5rem;\n padding: 1rem;\n }\n\n .editor-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n }\n\n .editor-header h2 { margin: 0; font-size: 1.25rem; }\n\n .providers-list { display: flex; flex-direction: column; gap: 1rem; }\n\n .provider-card {\n border: solid var(--wa-border-width-s) var(--wa-color-neutral-border-loud);\n border-radius: var(--wa-border-radius-m);\n overflow: hidden;\n }\n\n .provider-card-header {\n display: flex;\n align-items: center;\n gap: 0.75rem;\n padding: 0.5rem 0.75rem;\n background: var(--wa-color-surface-lowered);\n border-bottom: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .provider-card-header.is-default {\n background: var(--wa-color-brand-fill-quiet);\n border-bottom-color: var(--wa-color-brand-border-quiet);\n }\n\n .default-badge {\n font-size: 0.75rem;\n font-weight: 600;\n padding: 0.1rem 0.4rem;\n background: var(--wa-color-brand-fill-loud);\n color: var(--wa-color-brand-on-loud);\n border-radius: var(--wa-border-radius-s);\n text-transform: uppercase;\n letter-spacing: 0.04em;\n }\n\n .provider-name {\n font-weight: 500;\n flex: 1;\n }\n\n .provider-fields {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding: 0.75rem;\n }\n\n .field-row {\n display: grid;\n grid-template-columns: 120px 1fr;\n align-items: start;\n gap: 0.5rem;\n }\n\n .field-row label {\n font-size: 0.875rem;\n color: var(--wa-color-text-quiet);\n padding-top: 0.4rem;\n }\n\n .model-row { display: flex; gap: 0.25rem; align-items: center; }\n .model-row wa-input { flex: 1; }\n\n .settings-section {\n display: flex;\n flex-direction: column;\n gap: 0.75rem;\n padding-top: 1rem;\n border-top: solid var(--wa-border-width-s) var(--wa-color-neutral-border-subtle);\n }\n\n .settings-section h3 { margin: 0 0 0.5rem 0; font-size: 1rem; }\n\n .empty-state {\n display: flex;\n justify-content: center;\n padding: 3rem;\n color: var(--wa-color-text-subtle);\n }\n `;\n}\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'lyra-ai-config-editor': LyraAIConfigEditor;\n }\n}\n","import { html } from 'lit';\nimport { rootContext } from '@eclipse-lyra/core';\nimport { aiService } from './service/ai-service';\nimport { contributionRegistry } from '@eclipse-lyra/core';\nimport type { HTMLContribution } from '@eclipse-lyra/core';\nimport { editorRegistry } from '@eclipse-lyra/core';\nimport type { EditorInput } from '@eclipse-lyra/core';\nimport { registerAll, appSettings } from '@eclipse-lyra/core';\nimport { TOOLBAR_BOTTOM, TOOLBAR_MAIN_RIGHT, SIDEBAR_AUXILIARY } from '@eclipse-lyra/core';\nimport { CID_AGENTS, KEY_AI_CONFIG } from './core/constants';\nimport type { AgentContribution, AgentToolsConfig } from './core/interfaces';\nimport type { AIConfig } from './core/types';\nimport GENERAL_SYS_PROMPT from './general-assistant-prompt.txt?raw';\n\nimport './chat-provider-contributions';\nimport './prompt-enhancer-contributions';\nimport './view/aiview';\nimport './view/token-usage';\nimport './view/components/ai-config-editor';\n\ncontributionRegistry.registerContribution(SIDEBAR_AUXILIARY, {\n name: 'aiview',\n label: 'AI Assistant',\n icon: 'robot',\n component: (id: string) => html`<lyra-aiview id=\"${id}\"></lyra-aiview>`\n});\n\ncontributionRegistry.registerContribution(CID_AGENTS, {\n label: 'App Support',\n description: 'General-purpose assistant that can answer questions and execute app commands',\n role: 'appsupport',\n priority: 100,\n icon: 'question-circle',\n sysPrompt: GENERAL_SYS_PROMPT,\n tools: async () => {\n const config = await appSettings.get(KEY_AI_CONFIG) as AIConfig | undefined;\n return {\n enabled: true,\n smartToolDetection: config?.smartToolDetection ?? false\n } as AgentToolsConfig;\n }\n} as AgentContribution);\n\ncontributionRegistry.registerContribution(TOOLBAR_BOTTOM, {\n target: TOOLBAR_BOTTOM,\n label: 'Token Usage',\n component: '<lyra-token-usage></lyra-token-usage>'\n} as HTMLContribution);\n\neditorRegistry.registerEditorInputHandler({\n editorId: 'system.ai-config-editor',\n label: 'AI Config',\n ranking: 1000,\n canHandle: (input: EditorInput) => input.key === '.system.ai-config',\n handle: async (input: EditorInput) => {\n input.component = () => html`<lyra-ai-config-editor .input=\"${input}\"></lyra-ai-config-editor>`;\n return input;\n }\n});\n\nregisterAll({\n command: {\n id: 'open_ai_config',\n name: 'Open AI Configuration',\n description: 'Open the AI system configuration editor',\n parameters: []\n },\n handler: {\n execute: (_context: any) => {\n const editorInput: EditorInput = {\n title: 'AI Settings',\n data: {},\n key: '.system.ai-config',\n icon: 'robot',\n state: {}\n } as EditorInput;\n editorRegistry.loadEditor(editorInput).then();\n }\n },\n contribution: {\n target: TOOLBAR_MAIN_RIGHT,\n icon: 'robot',\n label: 'AI Config'\n }\n});\n\nrootContext.put('aiService', aiService);\n"],"names":["aiService","__decorateClass","globalCommandRegistry"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -4,7 +4,7 @@ extensionRegistry.registerExtension({
|
|
|
4
4
|
id: pkg.name,
|
|
5
5
|
name: "AI System",
|
|
6
6
|
description: "AI assistants, chat, and tool execution",
|
|
7
|
-
loader: () => import("./ai-system-extension-
|
|
7
|
+
loader: () => import("./ai-system-extension-Rr1JZnwv.js"),
|
|
8
8
|
icon: "robot"
|
|
9
9
|
});
|
|
10
10
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eclipse-lyra/extension-ai-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -30,5 +30,9 @@
|
|
|
30
30
|
"typescript": "^5.9.3",
|
|
31
31
|
"vite": "^7.1.12",
|
|
32
32
|
"vite-plugin-dts": "^4.5.4"
|
|
33
|
+
},
|
|
34
|
+
"repository": {
|
|
35
|
+
"type": "git",
|
|
36
|
+
"url": "https://github.com/eclipse-lyra/core"
|
|
33
37
|
}
|
|
34
38
|
}
|