diff --git a/crypto-pilot-builder/src/acceuil/Accueil.vue b/crypto-pilot-builder/src/acceuil/Accueil.vue index b378c8f..d20fac6 100644 --- a/crypto-pilot-builder/src/acceuil/Accueil.vue +++ b/crypto-pilot-builder/src/acceuil/Accueil.vue @@ -35,7 +35,7 @@ v-if="isAuthenticated" class="btn-icon" @click="showChat = false" - title="Retour" + title="Retour au dashboard" > 🏠️ @@ -131,13 +131,6 @@ 🤖 AutoWallet -
- + - - - - -
- - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/agent_building/Progress_bar.vue b/crypto-pilot-builder/src/agent_building/Progress_bar.vue index b587b6d..bdf26cf 100644 --- a/crypto-pilot-builder/src/agent_building/Progress_bar.vue +++ b/crypto-pilot-builder/src/agent_building/Progress_bar.vue @@ -35,7 +35,7 @@ export default { }, totalSteps: { type: Number, - default: 3 + default: 2 } }, computed: { @@ -59,16 +59,14 @@ export default { getStepTitle(step) { const titles = { 1: 'Configuration IA', - 2: 'Modules', - 3: 'Finalisation' + 2: 'Finalisation' }; return titles[step] || `Étape ${step}`; }, getStepSubtitle(step) { const subtitles = { 1: 'Modèle & API', - 2: 'Fonctionnalités', - 3: 'Prompt & Chat' + 2: 'Prompt & Chat' }; return subtitles[step] || ''; } diff --git a/crypto-pilot-builder/src/agent_building/Prompte.vue b/crypto-pilot-builder/src/agent_building/Prompte.vue index 5dcb2ae..6e90c3c 100644 --- a/crypto-pilot-builder/src/agent_building/Prompte.vue +++ b/crypto-pilot-builder/src/agent_building/Prompte.vue @@ -1,6 +1,6 @@ \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/App.vue b/crypto-pilot-builder/src/pipeline_agent/App.vue deleted file mode 100644 index 6f71c39..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/App.vue +++ /dev/null @@ -1,17 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/__tests__/Chatbot.test.js b/crypto-pilot-builder/src/pipeline_agent/__tests__/Chatbot.test.js deleted file mode 100644 index 84c0b9d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/__tests__/Chatbot.test.js +++ /dev/null @@ -1,382 +0,0 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' -import { mount } from '@vue/test-utils' -import { nextTick } from 'vue' -import Chatbot from '../components/chatbot.vue' - -// Mock des composants enfants -const mockChatSidebar = { - template: '
Chat Sidebar
', - props: ['chats', 'selectedChat'], - emits: ['select-chat', 'add-chat'] -} - -const mockChatMessages = { - template: '
Chat Messages
', - props: ['messages', 'isLoading'] -} - -const mockChatInput = { - template: '
Chat Input
', - emits: ['send-message'] -} - -// Mock du router -const mockRouter = { - push: vi.fn(), - replace: vi.fn(), - go: vi.fn(), - back: vi.fn(), - forward: vi.fn() -} - -describe('Chatbot.vue', () => { - let wrapper - let mockWalletFunctions - - beforeEach(() => { - // Reset des mocks - vi.clearAllMocks() - - // Mock de fetch - global.fetch = vi.fn() - - // Mock des wallet functions - mockWalletFunctions = { - isConnected: vi.fn(() => true), - getAddress: vi.fn(() => '0x1234567890123456789012345678901234567890'), - sendTransaction: vi.fn(() => Promise.resolve({ hash: '0xabcdef123456' })) - } - }) - - afterEach(() => { - if (wrapper) { - wrapper.unmount() - } - }) - - const createWrapper = (options = {}) => { - return mount(Chatbot, { - global: { - components: { - ChatSidebar: mockChatSidebar, - ChatMessages: mockChatMessages, - ChatInput: mockChatInput, - 'router-link': { - template: '', - props: ['to'] - } - }, - provide: { - walletFunctions: mockWalletFunctions - }, - mocks: { - $router: mockRouter, - $route: { path: '/chat' } - } - }, - ...options - }) - } - - describe('Initialisation du composant', () => { - it('devrait se monter correctement', () => { - wrapper = createWrapper() - expect(wrapper.exists()).toBe(true) - }) - - it('devrait afficher les composants enfants', async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - - wrapper = createWrapper() - await nextTick() - await new Promise(resolve => setTimeout(resolve, 0)) - expect(wrapper.findComponent(mockChatSidebar).exists()).toBe(true) - expect(wrapper.findComponent(mockChatMessages).exists()).toBe(true) - expect(wrapper.findComponent(mockChatInput).exists()).toBe(true) - }) - - it('devrait avoir un message initial', () => { - wrapper = createWrapper() - const messages = wrapper.vm.messages - expect(messages).toHaveLength(1) - expect(messages[0].text).toContain('Bonjour !') - expect(messages[0].isUser).toBe(false) - }) - - it('devrait créer une nouvelle session au montage', async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - wrapper = createWrapper() - await nextTick() - expect(global.fetch).toHaveBeenCalledWith( - 'http://localhost:5000/new-session', - expect.objectContaining({ - method: 'POST', - headers: { 'Content-Type': 'application/json' } - }) - ) - }) - }) - - describe('Gestion des messages', () => { - beforeEach(async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - wrapper = createWrapper() - await nextTick() - }) - - it('devrait envoyer un message utilisateur', async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ - response: 'Réponse du bot', - session_id: 'test-session-123' - }) - }) - const testMessage = 'Bonjour, comment ça va ?' - await wrapper.vm.sendMessage(testMessage) - const messages = wrapper.vm.messages - expect(messages.some(msg => msg.text === testMessage && msg.isUser === true)).toBe(true) - }) - - it('devrait gérer les réponses du bot', async () => { - const botResponse = 'Réponse du chatbot' - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ - response: botResponse, - session_id: 'test-session-123' - }) - }) - await wrapper.vm.sendMessage('Test message') - await nextTick() - const messages = wrapper.vm.messages - expect(messages.some(msg => msg.text === botResponse && msg.isUser === false)).toBe(true) - }) - - it('devrait gérer les erreurs de l\'API', async () => { - global.fetch.mockRejectedValueOnce(new Error('Erreur réseau')) - - await wrapper.vm.sendMessage('Test message') - await nextTick() - - const messages = wrapper.vm.messages - expect(messages.some(msg => msg.text.includes('Erreur de communication'))).toBe(true) - }) - - it('ne devrait pas envoyer de messages vides', async () => { - vi.clearAllMocks() - const initialMessageCount = wrapper.vm.messages.length - await wrapper.vm.sendMessage('') - await wrapper.vm.sendMessage(' ') - - expect(wrapper.vm.messages).toHaveLength(initialMessageCount) - expect(global.fetch).not.toHaveBeenCalled() - }) - }) - - describe('Gestion des transactions', () => { - beforeEach(async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - wrapper = createWrapper() - await nextTick() - }) - - it('devrait détecter une demande de transaction', async () => { - const transactionRequest = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ - response: 'Transaction détectée', - transaction_request: transactionRequest, - session_id: 'test-session-123' - }) - }) - - await wrapper.vm.sendMessage('Envoie 0.1 ETH à 0x1234567890123456789012345678901234567890') - await nextTick() - - expect(wrapper.vm.pendingTransaction).toEqual(transactionRequest) - }) - - it('devrait afficher la modal de confirmation', async () => { - wrapper.vm.pendingTransaction = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - await nextTick() - - const modal = wrapper.find('.transaction-modal-overlay') - expect(modal.exists()).toBe(true) - - const confirmBtn = wrapper.find('.confirm-btn') - const cancelBtn = wrapper.find('.cancel-btn') - expect(confirmBtn.exists()).toBe(true) - expect(cancelBtn.exists()).toBe(true) - }) - - it('devrait confirmer une transaction', async () => { - wrapper.vm.pendingTransaction = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ success: true }) - }) - await wrapper.vm.confirmTransaction() - expect(mockWalletFunctions.sendTransaction).toHaveBeenCalledWith( - '0x1234567890123456789012345678901234567890', - '0.1' - ) - expect(wrapper.vm.pendingTransaction).toBeNull() - }) - - it('devrait annuler une transaction', async () => { - wrapper.vm.pendingTransaction = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ success: true }) - }) - - await wrapper.vm.cancelTransaction() - - expect(wrapper.vm.pendingTransaction).toBeNull() - const messages = wrapper.vm.messages - expect(messages.some(msg => msg.text.includes('Transaction annulée'))).toBe(true) - }) - - it('devrait gérer les erreurs de wallet non connecté', async () => { - mockWalletFunctions.isConnected.mockReturnValue(false) - - wrapper.vm.pendingTransaction = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - - await wrapper.vm.confirmTransaction() - - const messages = wrapper.vm.messages - expect(messages.some(msg => msg.text.includes('Wallet non connecté'))).toBe(true) - expect(wrapper.vm.pendingTransaction).toBeNull() - }) - }) - - describe('Gestion des chats', () => { - beforeEach(async () => { - global.fetch.mockResolvedValue({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - wrapper = createWrapper() - await nextTick() - }) - - it('devrait créer un nouveau chat', async () => { - const initialChatCount = wrapper.vm.chats.length - await wrapper.vm.addNewChat() - - expect(wrapper.vm.chats.length).toBeGreaterThan(initialChatCount) - }) - - it('devrait sélectionner un chat existant', async () => { - wrapper.vm.chats.push('Test Chat') - wrapper.vm.chatSessions['Test Chat'] = { - sessionId: 'test-session-456', - messages: [{ text: 'Test message', isUser: false }] - } - - wrapper.vm.selectChat(wrapper.vm.chats.length - 1) - - expect(wrapper.vm.currentSessionId).toBe('test-session-456') - expect(wrapper.vm.messages).toEqual([{ text: 'Test message', isUser: false }]) - }) - }) - - describe('Fonctions utilitaires', () => { - beforeEach(() => { - wrapper = createWrapper() - }) - it('devrait gérer l\'absence de wallet', () => { - wrapper = createWrapper({ - global: { - components: { - ChatSidebar: mockChatSidebar, - ChatMessages: mockChatMessages, - ChatInput: mockChatInput, - 'router-link': { - template: '', - props: ['to'] - } - }, - provide: { - walletFunctions: null - }, - mocks: { - $router: mockRouter, - $route: { path: '/chat' } - } - } - }) - - }) - }) - - describe('Interface utilisateur', () => { - beforeEach(async () => { - global.fetch.mockResolvedValueOnce({ - ok: true, - json: () => Promise.resolve({ session_id: 'test-session-123' }) - }) - wrapper = createWrapper() - await nextTick() - }) - - it('devrait afficher l\'en-tête avec l\'ID de session', async () => { - wrapper.vm.currentSessionId = 'test-session-123456789' - await nextTick() - - const header = wrapper.find('.chat-header h3') - expect(header.text()).toContain('test-ses...') - }) - - it('devrait fermer la modal en cliquant sur l\'overlay', async () => { - wrapper.vm.pendingTransaction = { - recipient: '0x1234567890123456789012345678901234567890', - amount: '0.1', - currency: 'eth' - } - await nextTick() - - const overlay = wrapper.find('.transaction-modal-overlay') - await overlay.trigger('click') - - expect(wrapper.vm.pendingTransaction).toBeNull() - }) - }) -}) \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/__tests__/Wallet.test.js b/crypto-pilot-builder/src/pipeline_agent/__tests__/Wallet.test.js deleted file mode 100644 index fe03a44..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/__tests__/Wallet.test.js +++ /dev/null @@ -1,247 +0,0 @@ -import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest' -import { mount } from '@vue/test-utils' -import { nextTick } from 'vue' -import Wallet from '../components/wallet.vue' -import { createWalletClient, custom } from 'viem' - -// Mock de viem - déplacé en haut du fichier -vi.mock('viem', () => ({ - createWalletClient: vi.fn(), - custom: vi.fn(), - parseEther: vi.fn((amount) => `parsed_${amount}`), -})) - -vi.mock('viem/chains', () => ({ - sepolia: { id: 11155111, name: 'Sepolia' } -})) - -describe('Wallet.vue', () => { - let wrapper - let mockEthereum - let mockWalletClient - - beforeEach(() => { - // Reset des mocks - vi.clearAllMocks() - - // Mock de window.ethereum - mockEthereum = { - request: vi.fn(), - isMetaMask: true - } - - // Mock du wallet client - mockWalletClient = { - sendTransaction: vi.fn() - } - - // Configuration des mocks viem - createWalletClient.mockReturnValue(mockWalletClient) - custom.mockReturnValue('mocked-transport') - - // Simuler la présence de MetaMask - global.window = { - ethereum: mockEthereum - } - }) - - afterEach(() => { - if (wrapper) { - wrapper.unmount() - } - }) - - const createWrapper = (options = {}) => { - return mount(Wallet, { - ...options - }) - } - - describe('Initialisation du composant', () => { - it('devrait se monter correctement', () => { - wrapper = createWrapper() - expect(wrapper.exists()).toBe(true) - }) - - it('devrait afficher le composant wallet', () => { - wrapper = createWrapper() - expect(wrapper.find('.wallet-connect').exists()).toBe(true) - }) - - it('devrait afficher le bouton de connexion initialement', () => { - wrapper = createWrapper() - const connectButton = wrapper.find('.connect-button') - expect(connectButton.exists()).toBe(true) - expect(connectButton.text()).toBe('🔗 Connecter') - }) - - it('ne devrait pas afficher les informations du wallet initialement', () => { - wrapper = createWrapper() - const walletInfo = wrapper.find('.wallet-info') - expect(walletInfo.exists()).toBe(false) - }) - }) - - describe('Connexion au wallet', () => { - it('devrait connecter le wallet avec succès', async () => { - const testAddress = '0x1234567890123456789012345678901234567890' - mockEthereum.request.mockResolvedValueOnce([testAddress]) - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - expect(mockEthereum.request).toHaveBeenCalledWith({ - method: 'eth_requestAccounts' - }) - expect(wrapper.vm.address).toBe(testAddress) - expect(wrapper.vm.status).toBe('✅ Wallet connecté automatiquement') - }) - - it('devrait afficher les informations du wallet après connexion', async () => { - const testAddress = '0x1234567890123456789012345678901234567890' - mockEthereum.request.mockResolvedValueOnce([testAddress]) - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - const walletInfo = wrapper.find('.wallet-info') - const connectButton = wrapper.find('.connect-button') - expect(walletInfo.exists()).toBe(true) - expect(walletInfo.text()).toBe('0x12...7890') - expect(connectButton.exists()).toBe(false) - }) - - it('devrait gérer l\'absence de MetaMask', async () => { - global.window.ethereum = undefined - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - expect(wrapper.vm.status).toBe('🦊 MetaMask non trouvé') - expect(wrapper.vm.address).toBeNull() - }) - - it('devrait gérer les erreurs de connexion', async () => { - mockEthereum.request.mockRejectedValueOnce(new Error('User rejected')) - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - expect(wrapper.vm.status).toBe('✏️ Saisissez votre adresse manuellement') - expect(wrapper.vm.address).toBeNull() - }) - - it('devrait déclencher la connexion au clic sur le bouton', async () => { - const testAddress = '0x1234567890123456789012345678901234567890' - mockEthereum.request.mockResolvedValueOnce([testAddress]) - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - expect(wrapper.vm.address).toBe(testAddress) - }) - }) - - describe('Envoi de transactions', () => { - const testAddress = '0x1234567890123456789012345678901234567890' - const recipientAddress = '0x9876543210987654321098765432109876543210' - const amount = '0.1' - const txHash = '0xabcdef123456789abcdef123456789abcdef123456' - - beforeEach(async () => { - mockEthereum.request.mockResolvedValueOnce([testAddress]) - wrapper = createWrapper() - await wrapper.vm.connectWallet() - await nextTick() - }) - - it('devrait envoyer une transaction avec succès', async () => { - mockWalletClient.sendTransaction.mockResolvedValueOnce(txHash) - const result = await wrapper.vm.sendTransactionFromChat(recipientAddress, amount) - expect(mockWalletClient.sendTransaction).toHaveBeenCalledWith({ - account: testAddress, - to: recipientAddress, - value: `parsed_${amount}` - }) - expect(result.success).toBe(true) - expect(result.hash).toBe(txHash) - expect(wrapper.vm.status).toContain('✅ Tx envoyée') - expect(wrapper.vm.isProcessing).toBe(false) - }) - - it('devrait gérer le rejet de la transaction par l\'utilisateur', async () => { - const userRejectedError = new Error('User rejected the request') - mockWalletClient.sendTransaction.mockRejectedValueOnce(userRejectedError) - await expect(wrapper.vm.sendTransactionFromChat(recipientAddress, amount)) - .rejects.toThrow('❌ Rejeté') - expect(wrapper.vm.status).toBe('❌ Rejeté') - expect(wrapper.vm.isProcessing).toBe(false) - }) - - it('devrait gérer les fonds insuffisants', async () => { - const insufficientFundsError = new Error('insufficient funds for intrinsic transaction cost') - mockWalletClient.sendTransaction.mockRejectedValueOnce(insufficientFundsError) - await expect(wrapper.vm.sendTransactionFromChat(recipientAddress, amount)) - .rejects.toThrow('💸 Fonds insuffisants') - expect(wrapper.vm.status).toBe('💸 Fonds insuffisants') - }) - - it('devrait rejeter si le wallet n\'est pas connecté', async () => { - wrapper.vm.address = null - await expect(wrapper.vm.sendTransactionFromChat(recipientAddress, amount)) - .rejects.toThrow('Wallet non connecté') - }) - - it('devrait rejeter si les paramètres sont manquants', async () => { - await expect(wrapper.vm.sendTransactionFromChat('', amount)) - .rejects.toThrow('Adresse ou montant manquant') - await expect(wrapper.vm.sendTransactionFromChat(recipientAddress, '')) - .rejects.toThrow('Adresse ou montant manquant') - }) - }) - - describe('Fonctions utilitaires', () => { - beforeEach(() => { - wrapper = createWrapper() - }) - - it('devrait raccourcir les adresses correctement', () => { - const longAddress = '0x1234567890123456789012345678901234567890' - const shortened = wrapper.vm.shortenAddress(longAddress) - expect(shortened).toBe('0x12...7890') - }) - - it('devrait retourner une chaîne vide pour les adresses nulles', () => { - expect(wrapper.vm.shortenAddress(null)).toBe('') - expect(wrapper.vm.shortenAddress(undefined)).toBe('') - expect(wrapper.vm.shortenAddress('')).toBe('') - }) - - it('devrait indiquer si le wallet est connecté', () => { - expect(wrapper.vm.isConnected()).toBe(false) - wrapper.vm.address = '0x1234567890123456789012345678901234567890' - expect(wrapper.vm.isConnected()).toBe(true) - }) - }) - - describe('Interface utilisateur', () => { - it('devrait afficher le statut quand il existe', async () => { - wrapper = createWrapper() - wrapper.vm.status = 'Test status message' - await nextTick() - const statusElement = wrapper.find('.status') - expect(statusElement.exists()).toBe(true) - expect(statusElement.text()).toBe('Test status message') - }) - - it('ne devrait pas afficher le statut quand il est vide', async () => { - wrapper = createWrapper() - wrapper.vm.status = '' - await nextTick() - const statusElement = wrapper.find('.status') - expect(statusElement.exists()).toBe(false) - }) - - it('devrait appliquer les bonnes classes CSS', () => { - wrapper = createWrapper() - expect(wrapper.find('.wallet-connect').exists()).toBe(true) - expect(wrapper.find('.top-bar').exists()).toBe(true) - expect(wrapper.find('.actions').exists()).toBe(true) - }) - }) -}) \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/acceuil/Accueil.vue b/crypto-pilot-builder/src/pipeline_agent/acceuil/Accueil.vue deleted file mode 100644 index b378c8f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/acceuil/Accueil.vue +++ /dev/null @@ -1,3698 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/acceuil/Chat_Page.vue b/crypto-pilot-builder/src/pipeline_agent/acceuil/Chat_Page.vue deleted file mode 100644 index 7bbcd6f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/acceuil/Chat_Page.vue +++ /dev/null @@ -1,160 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/agent_building/Ai.vue b/crypto-pilot-builder/src/pipeline_agent/agent_building/Ai.vue deleted file mode 100644 index 749fd9d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/agent_building/Ai.vue +++ /dev/null @@ -1,598 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/agent_building/Module.vue b/crypto-pilot-builder/src/pipeline_agent/agent_building/Module.vue deleted file mode 100644 index 1b7518d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/agent_building/Module.vue +++ /dev/null @@ -1,622 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/agent_building/Progress_bar.vue b/crypto-pilot-builder/src/pipeline_agent/agent_building/Progress_bar.vue deleted file mode 100644 index b587b6d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/agent_building/Progress_bar.vue +++ /dev/null @@ -1,307 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/agent_building/Prompte.vue b/crypto-pilot-builder/src/pipeline_agent/agent_building/Prompte.vue deleted file mode 100644 index 5dcb2ae..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/agent_building/Prompte.vue +++ /dev/null @@ -1,915 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/assets/base.css b/crypto-pilot-builder/src/pipeline_agent/assets/base.css deleted file mode 100644 index 8816868..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/assets/base.css +++ /dev/null @@ -1,86 +0,0 @@ -/* color palette from */ -:root { - --vt-c-white: #ffffff; - --vt-c-white-soft: #f8f8f8; - --vt-c-white-mute: #f2f2f2; - - --vt-c-black: #181818; - --vt-c-black-soft: #222222; - --vt-c-black-mute: #282828; - - --vt-c-indigo: #2c3e50; - - --vt-c-divider-light-1: rgba(60, 60, 60, 0.29); - --vt-c-divider-light-2: rgba(60, 60, 60, 0.12); - --vt-c-divider-dark-1: rgba(84, 84, 84, 0.65); - --vt-c-divider-dark-2: rgba(84, 84, 84, 0.48); - - --vt-c-text-light-1: var(--vt-c-indigo); - --vt-c-text-light-2: rgba(60, 60, 60, 0.66); - --vt-c-text-dark-1: var(--vt-c-white); - --vt-c-text-dark-2: rgba(235, 235, 235, 0.64); -} - -/* semantic color variables for this project */ -:root { - --color-background: var(--vt-c-white); - --color-background-soft: var(--vt-c-white-soft); - --color-background-mute: var(--vt-c-white-mute); - - --color-border: var(--vt-c-divider-light-2); - --color-border-hover: var(--vt-c-divider-light-1); - - --color-heading: var(--vt-c-text-light-1); - --color-text: var(--vt-c-text-light-1); - - --section-gap: 160px; -} - -@media (prefers-color-scheme: dark) { - :root { - --color-background: var(--vt-c-black); - --color-background-soft: var(--vt-c-black-soft); - --color-background-mute: var(--vt-c-black-mute); - - --color-border: var(--vt-c-divider-dark-2); - --color-border-hover: var(--vt-c-divider-dark-1); - - --color-heading: var(--vt-c-text-dark-1); - --color-text: var(--vt-c-text-dark-2); - } -} - -*, -*::before, -*::after { - box-sizing: border-box; - margin: 0; - font-weight: normal; -} - -body { - min-height: 100vh; - color: var(--color-text); - background: var(--color-background); - transition: - color 0.5s, - background-color 0.5s; - line-height: 1.6; - font-family: - Inter, - -apple-system, - BlinkMacSystemFont, - 'Segoe UI', - Roboto, - Oxygen, - Ubuntu, - Cantarell, - 'Fira Sans', - 'Droid Sans', - 'Helvetica Neue', - sans-serif; - font-size: 15px; - text-rendering: optimizeLegibility; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} diff --git a/crypto-pilot-builder/src/pipeline_agent/assets/logo.svg b/crypto-pilot-builder/src/pipeline_agent/assets/logo.svg deleted file mode 100644 index 7565660..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/assets/logo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/crypto-pilot-builder/src/pipeline_agent/assets/main.css b/crypto-pilot-builder/src/pipeline_agent/assets/main.css deleted file mode 100644 index 36fb845..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/assets/main.css +++ /dev/null @@ -1,35 +0,0 @@ -@import './base.css'; - -#app { - max-width: 1280px; - margin: 0 auto; - padding: 2rem; - font-weight: normal; -} - -a, -.green { - text-decoration: none; - color: hsla(160, 100%, 37%, 1); - transition: 0.4s; - padding: 3px; -} - -@media (hover: hover) { - a:hover { - background-color: hsla(160, 100%, 37%, 0.2); - } -} - -@media (min-width: 1024px) { - body { - display: flex; - place-items: center; - } - - #app { - display: grid; - grid-template-columns: 1fr 1fr; - padding: 0 2rem; - } -} diff --git a/crypto-pilot-builder/src/pipeline_agent/components/AddChannelForm.vue b/crypto-pilot-builder/src/pipeline_agent/components/AddChannelForm.vue deleted file mode 100644 index 57ee295..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/AddChannelForm.vue +++ /dev/null @@ -1,309 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/AgentConfigManager.vue b/crypto-pilot-builder/src/pipeline_agent/components/AgentConfigManager.vue deleted file mode 100644 index 9fd7c9f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/AgentConfigManager.vue +++ /dev/null @@ -1,476 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/AuthModal.vue b/crypto-pilot-builder/src/pipeline_agent/components/AuthModal.vue deleted file mode 100644 index 65ec2f6..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/AuthModal.vue +++ /dev/null @@ -1,745 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/components/AutoWallet.vue b/crypto-pilot-builder/src/pipeline_agent/components/AutoWallet.vue deleted file mode 100644 index 00fda8d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/AutoWallet.vue +++ /dev/null @@ -1,1610 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/EditConfigForm.vue b/crypto-pilot-builder/src/pipeline_agent/components/EditConfigForm.vue deleted file mode 100644 index a658f57..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/EditConfigForm.vue +++ /dev/null @@ -1,211 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/Modal.vue b/crypto-pilot-builder/src/pipeline_agent/components/Modal.vue deleted file mode 100644 index a2a3365..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/Modal.vue +++ /dev/null @@ -1,109 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/TradingPipeline.vue b/crypto-pilot-builder/src/pipeline_agent/components/TradingPipeline.vue deleted file mode 100644 index 801e0a1..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/TradingPipeline.vue +++ /dev/null @@ -1,878 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/UserMemory.vue b/crypto-pilot-builder/src/pipeline_agent/components/UserMemory.vue deleted file mode 100644 index 9842ad2..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/UserMemory.vue +++ /dev/null @@ -1,887 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/BentoGrid.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/BentoGrid.vue deleted file mode 100644 index dcee332..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/BentoGrid.vue +++ /dev/null @@ -1,509 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/CryptoWidget.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/CryptoWidget.vue deleted file mode 100644 index b5455dc..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/CryptoWidget.vue +++ /dev/null @@ -1,137 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/MainCryptoWidget.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/MainCryptoWidget.vue deleted file mode 100644 index a27976c..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/MainCryptoWidget.vue +++ /dev/null @@ -1,598 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/NewsWidget.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/NewsWidget.vue deleted file mode 100644 index 60493d6..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/NewsWidget.vue +++ /dev/null @@ -1,174 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/StatsWidget.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/StatsWidget.vue deleted file mode 100644 index 9c50f01..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/StatsWidget.vue +++ /dev/null @@ -1,163 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/TrendingWidget.vue b/crypto-pilot-builder/src/pipeline_agent/components/bento/TrendingWidget.vue deleted file mode 100644 index 6816efc..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/TrendingWidget.vue +++ /dev/null @@ -1,246 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/bento/index.js b/crypto-pilot-builder/src/pipeline_agent/components/bento/index.js deleted file mode 100644 index e17beb3..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/bento/index.js +++ /dev/null @@ -1,7 +0,0 @@ -// Export de tous les composants Bento -export { default as BentoGrid } from "./BentoGrid.vue"; -export { default as MainCryptoWidget } from "./MainCryptoWidget.vue"; -export { default as NewsWidget } from "./NewsWidget.vue"; -export { default as StatsWidget } from "./StatsWidget.vue"; -export { default as CryptoWidget } from "./CryptoWidget.vue"; -export { default as TrendingWidget } from "./TrendingWidget.vue"; diff --git a/crypto-pilot-builder/src/pipeline_agent/components/chatbot.vue b/crypto-pilot-builder/src/pipeline_agent/components/chatbot.vue deleted file mode 100644 index 7b81a71..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/chatbot.vue +++ /dev/null @@ -1,1705 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatInput.vue b/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatInput.vue deleted file mode 100644 index 01d0047..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatInput.vue +++ /dev/null @@ -1,81 +0,0 @@ - - - - - diff --git a/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatMessages.vue b/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatMessages.vue deleted file mode 100644 index 3d9ae27..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/chatbot/ChatMessages.vue +++ /dev/null @@ -1,144 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/components/wallet.vue b/crypto-pilot-builder/src/pipeline_agent/components/wallet.vue deleted file mode 100644 index fd3a844..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/components/wallet.vue +++ /dev/null @@ -1,944 +0,0 @@ - - - - - \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/composables/useSessionManager.js b/crypto-pilot-builder/src/pipeline_agent/composables/useSessionManager.js deleted file mode 100644 index 5541267..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/composables/useSessionManager.js +++ /dev/null @@ -1,287 +0,0 @@ -import { ref, computed } from 'vue' -import apiService from '../services/apiService' - -// Global session state -const sessions = ref(new Map()) -const activeSessionId = ref(null) -const isLoading = ref(false) -const error = ref('') - -export function useSessionManager() { - // Computed - const activeSessions = computed(() => { - return Array.from(sessions.value.values()).sort((a, b) => - new Date(b.lastActivity) - new Date(a.lastActivity) - ) - }) - - const activeSession = computed(() => { - return activeSessionId.value ? sessions.value.get(activeSessionId.value) : null - }) - - const activeMessages = computed(() => { - return activeSession.value?.messages || [] - }) - - // Methods - const createSession = async (name = null) => { - isLoading.value = true - error.value = '' - - try { - const sessionName = name || `Chat ${Date.now()}` - const response = await apiService.createNewSession(sessionName) - - const session = { - id: response.session_id, - name: sessionName, - messages: [], - createdAt: new Date().toISOString(), - lastActivity: new Date().toISOString() - } - - sessions.value.set(session.id, session) - activeSessionId.value = session.id - - console.log('Session created:', session.id) - return session - - } catch (err) { - console.error('Error creating session:', err) - error.value = 'Erreur lors de la création de la session' - throw err - } finally { - isLoading.value = false - } - } - - const loadSession = async (sessionId) => { - if (!sessionId) return null - - isLoading.value = true - error.value = '' - - try { - const response = await apiService.getSession(sessionId) - - const messages = (response.messages || []).map(msg => ({ - text: msg.content || msg.text || '', - isUser: msg.role === 'user', - created_at: msg.created_at || msg.timestamp || new Date().toISOString() - })) - - const session = { - id: sessionId, - name: response.session_name || `Session ${sessionId.substring(0, 8)}`, - messages, - createdAt: response.created_at || new Date().toISOString(), - lastActivity: new Date().toISOString() - } - - sessions.value.set(sessionId, session) - activeSessionId.value = sessionId - - console.log('Session loaded:', sessionId, 'with', messages.length, 'messages') - return session - - } catch (err) { - console.error('Error loading session:', err) - error.value = 'Erreur lors du chargement de la session' - throw err - } finally { - isLoading.value = false - } - } - - const loadAllSessions = async () => { - isLoading.value = true - error.value = '' - - try { - const response = await apiService.listSessions() - const sessionList = response.sessions || [] - - // Clear existing sessions - sessions.value.clear() - - // Load each session - for (const sessionInfo of sessionList) { - try { - await loadSession(sessionInfo.session_id) - } catch (err) { - console.error('Error loading session:', sessionInfo.session_id, err) - // Continue loading other sessions even if one fails - } - } - - // Set active session to the most recent one - if (activeSessions.value.length > 0) { - activeSessionId.value = activeSessions.value[0].id - } - - console.log('Loaded', sessions.value.size, 'sessions') - return activeSessions.value - - } catch (err) { - console.error('Error loading sessions:', err) - error.value = 'Erreur lors du chargement des sessions' - throw err - } finally { - isLoading.value = false - } - } - - const selectSession = async (sessionId) => { - if (!sessionId) return null - - // If session is already loaded, just switch to it - if (sessions.value.has(sessionId)) { - activeSessionId.value = sessionId - updateLastActivity(sessionId) - return sessions.value.get(sessionId) - } - - // Otherwise, load it first - return await loadSession(sessionId) - } - - const renameSession = async (sessionId, newName) => { - if (!sessionId || !newName?.trim()) return false - - try { - // Update locally first - const session = sessions.value.get(sessionId) - if (session) { - session.name = newName.trim() - session.lastActivity = new Date().toISOString() - sessions.value.set(sessionId, session) - } - - // Update on server (if API supports it) - await apiService.renameSession(sessionId, newName.trim()) - - console.log('Session renamed:', sessionId, 'to', newName) - return true - - } catch (err) { - console.error('Error renaming session:', err) - error.value = 'Erreur lors du renommage de la session' - return false - } - } - - const deleteSession = async (sessionId) => { - if (!sessionId) return false - - try { - // Delete on server first - await apiService.deleteSession(sessionId) - - // Remove from local state - sessions.value.delete(sessionId) - - // If this was the active session, switch to another one - if (activeSessionId.value === sessionId) { - const remainingSessions = activeSessions.value - activeSessionId.value = remainingSessions.length > 0 ? remainingSessions[0].id : null - } - - console.log('Session deleted:', sessionId) - return true - - } catch (err) { - console.error('Error deleting session:', err) - error.value = 'Erreur lors de la suppression de la session' - return false - } - } - - const addMessage = (sessionId, message) => { - const session = sessions.value.get(sessionId) - if (!session) return false - - const messageWithTimestamp = { - ...message, - created_at: message.created_at || new Date().toISOString() - } - - session.messages.push(messageWithTimestamp) - session.lastActivity = new Date().toISOString() - sessions.value.set(sessionId, session) - - return true - } - - const addMessages = (sessionId, messages) => { - if (!Array.isArray(messages)) return false - - const session = sessions.value.get(sessionId) - if (!session) return false - - const messagesWithTimestamp = messages.map(msg => ({ - ...msg, - created_at: msg.created_at || new Date().toISOString() - })) - - session.messages.push(...messagesWithTimestamp) - session.lastActivity = new Date().toISOString() - sessions.value.set(sessionId, session) - - return true - } - - const updateLastActivity = (sessionId) => { - const session = sessions.value.get(sessionId) - if (session) { - session.lastActivity = new Date().toISOString() - sessions.value.set(sessionId, session) - } - } - - const clearError = () => { - error.value = '' - } - - const getSessionById = (sessionId) => { - return sessions.value.get(sessionId) || null - } - - const getSessionsAsArray = () => { - return activeSessions.value.map(session => ({ - id: session.id, - name: session.name - })) - } - - return { - // State - sessions: readonly(sessions), - activeSessionId: readonly(activeSessionId), - isLoading: readonly(isLoading), - error: readonly(error), - - // Computed - activeSessions, - activeSession, - activeMessages, - - // Methods - createSession, - loadSession, - loadAllSessions, - selectSession, - renameSession, - deleteSession, - addMessage, - addMessages, - updateLastActivity, - clearError, - getSessionById, - getSessionsAsArray - } -} - -// Helper function to make refs readonly -function readonly(ref) { - return computed(() => ref.value) -} diff --git a/crypto-pilot-builder/src/pipeline_agent/composables/useWalletService.js b/crypto-pilot-builder/src/pipeline_agent/composables/useWalletService.js deleted file mode 100644 index b56b38f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/composables/useWalletService.js +++ /dev/null @@ -1,287 +0,0 @@ -import { ref, computed } from 'vue' -import { createWalletClient, custom, parseEther, formatEther } from 'viem' -import { mainnet } from 'viem/chains' - -// Global wallet state -const walletAddress = ref('') -const isConnected = ref(false) -const isConnecting = ref(false) -const walletClient = ref(null) -const connectionError = ref('') - -export function useWalletService() { - // Computed - const formattedAddress = computed(() => { - if (!walletAddress.value) return '' - return `${walletAddress.value.substring(0, 6)}...${walletAddress.value.substring(walletAddress.value.length - 4)}` - }) - - const hasMetaMask = computed(() => { - return typeof window !== 'undefined' && window.ethereum && window.ethereum.isMetaMask - }) - - // Methods - const connectWallet = async () => { - if (!hasMetaMask.value) { - connectionError.value = 'MetaMask n\'est pas installé. Veuillez l\'installer pour continuer.' - return false - } - - isConnecting.value = true - connectionError.value = '' - - try { - // Request account access - const accounts = await window.ethereum.request({ - method: 'eth_requestAccounts' - }) - - if (accounts.length === 0) { - throw new Error('Aucun compte sélectionné') - } - - // Create wallet client - walletClient.value = createWalletClient({ - chain: mainnet, - transport: custom(window.ethereum) - }) - - walletAddress.value = accounts[0] - isConnected.value = true - - // Listen for account changes - window.ethereum.on('accountsChanged', handleAccountsChanged) - window.ethereum.on('chainChanged', handleChainChanged) - - console.log('Wallet connected:', walletAddress.value) - return true - - } catch (error) { - console.error('Error connecting wallet:', error) - connectionError.value = error.message || 'Erreur lors de la connexion au portefeuille' - return false - } finally { - isConnecting.value = false - } - } - - const disconnectWallet = () => { - walletAddress.value = '' - isConnected.value = false - walletClient.value = null - connectionError.value = '' - - // Remove event listeners - if (window.ethereum) { - window.ethereum.removeListener('accountsChanged', handleAccountsChanged) - window.ethereum.removeListener('chainChanged', handleChainChanged) - } - - console.log('Wallet disconnected') - } - - const setManualAddress = (address) => { - if (!address || !isValidAddress(address)) { - connectionError.value = 'Adresse invalide' - return false - } - - walletAddress.value = address - isConnected.value = true - connectionError.value = '' - - console.log('Manual address set:', address) - return true - } - - const validateAddress = async () => { - if (!walletAddress.value) { - connectionError.value = 'Aucune adresse à valider' - return false - } - - try { - // Simple validation - check if it's a valid Ethereum address - if (!isValidAddress(walletAddress.value)) { - throw new Error('Format d\'adresse invalide') - } - - // You could add more validation here (e.g., check balance, verify on blockchain) - console.log('Address validated:', walletAddress.value) - return true - - } catch (error) { - console.error('Error validating address:', error) - connectionError.value = error.message || 'Erreur lors de la validation' - return false - } - } - - const sendTransaction = async (to, amount) => { - if (!isConnected.value || !walletClient.value) { - throw new Error('Portefeuille non connecté') - } - - if (!to || !amount) { - throw new Error('Destinataire et montant requis') - } - - if (!isValidAddress(to)) { - throw new Error('Adresse de destinataire invalide') - } - - try { - const amountInWei = parseEther(amount.toString()) - - const hash = await walletClient.value.sendTransaction({ - account: walletAddress.value, - to: to, - value: amountInWei - }) - - console.log('Transaction sent:', hash) - - return { - hash, - to, - amount, - from: walletAddress.value, - timestamp: new Date().toISOString() - } - - } catch (error) { - console.error('Error sending transaction:', error) - throw new Error(error.message || 'Erreur lors de l\'envoi de la transaction') - } - } - - const getBalance = async () => { - if (!isConnected.value || !walletAddress.value) { - return '0' - } - - try { - const balance = await window.ethereum.request({ - method: 'eth_getBalance', - params: [walletAddress.value, 'latest'] - }) - - // Convert from wei to ether - const balanceInEther = formatEther(BigInt(balance)) - return parseFloat(balanceInEther).toFixed(4) - - } catch (error) { - console.error('Error getting balance:', error) - return '0' - } - } - - const estimateGas = async (to, amount) => { - if (!isConnected.value || !walletClient.value) { - return '0' - } - - try { - const amountInWei = parseEther(amount.toString()) - - const gasEstimate = await walletClient.value.estimateGas({ - account: walletAddress.value, - to: to, - value: amountInWei - }) - - // Get current gas price - const gasPrice = await window.ethereum.request({ - method: 'eth_gasPrice' - }) - - // Calculate total gas cost in ether - const gasCost = (gasEstimate * BigInt(gasPrice)) - return formatEther(gasCost) - - } catch (error) { - console.error('Error estimating gas:', error) - return '0' - } - } - - // Event handlers - const handleAccountsChanged = (accounts) => { - if (accounts.length === 0) { - disconnectWallet() - } else { - walletAddress.value = accounts[0] - console.log('Account changed:', accounts[0]) - } - } - - const handleChainChanged = (chainId) => { - console.log('Chain changed:', chainId) - // You might want to handle chain changes here - // For now, we'll just log it - } - - // Utility functions - const isValidAddress = (address) => { - return /^0x[a-fA-F0-9]{40}$/.test(address) - } - - // Auto-connect on page load if previously connected - const autoConnect = async () => { - if (!hasMetaMask.value) return - - try { - const accounts = await window.ethereum.request({ - method: 'eth_accounts' - }) - - if (accounts.length > 0) { - walletClient.value = createWalletClient({ - chain: mainnet, - transport: custom(window.ethereum) - }) - - walletAddress.value = accounts[0] - isConnected.value = true - - // Set up event listeners - window.ethereum.on('accountsChanged', handleAccountsChanged) - window.ethereum.on('chainChanged', handleChainChanged) - - console.log('Auto-connected to wallet:', walletAddress.value) - } - } catch (error) { - console.error('Error auto-connecting wallet:', error) - } - } - - // Initialize auto-connect - if (typeof window !== 'undefined') { - autoConnect() - } - - return { - // State - walletAddress: readonly(walletAddress), - isConnected: readonly(isConnected), - isConnecting: readonly(isConnecting), - connectionError: readonly(connectionError), - formattedAddress, - hasMetaMask, - - // Methods - connectWallet, - disconnectWallet, - setManualAddress, - validateAddress, - sendTransaction, - getBalance, - estimateGas, - autoConnect - } -} - -// Helper function to make refs readonly -function readonly(ref) { - return computed(() => ref.value) -} diff --git a/crypto-pilot-builder/src/pipeline_agent/renderer.js b/crypto-pilot-builder/src/pipeline_agent/renderer.js deleted file mode 100644 index b975193..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/renderer.js +++ /dev/null @@ -1,13 +0,0 @@ -import { createApp } from 'vue' -import App from './App.vue' -import router from './router' -import store from './store' -import ElementPlus from 'element-plus' -import 'element-plus/dist/index.css' - -const app = createApp(App) - -app.use(router) -app.use(store) -app.use(ElementPlus) -app.mount('#app') \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/router/index.js b/crypto-pilot-builder/src/pipeline_agent/router/index.js deleted file mode 100644 index acc487f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/router/index.js +++ /dev/null @@ -1,86 +0,0 @@ -import { createRouter, createWebHashHistory } from "vue-router"; -import Accueil from "../acceuil/Accueil.vue"; -import AI from "../agent_building/Ai.vue"; -import Module from "../agent_building/Module.vue"; -import Prompte from "../agent_building/Prompte.vue"; -import ChatPage from "../acceuil/Chat_Page.vue"; -import UserMemory from "../components/UserMemory.vue"; -import AutoWallet from "../components/AutoWallet.vue"; -import store from "../store"; - -const routes = [ - { - path: "/", - name: "Accueil", - component: Accueil, - }, - { - path: "/Model", - redirect: "/AI", - }, - { - path: "/AI", - name: "AI", - component: AI, - meta: { requiresAuth: true }, - }, - { - path: "/Module", - name: "Module", - component: Module, - meta: { requiresAuth: true }, - }, - { - path: "/Prompte", - name: "Prompte", - component: Prompte, - meta: { requiresAuth: true }, - }, - { - path: "/chat", - name: "Chat", - component: ChatPage, - meta: { requiresAuth: true }, - }, - { - path: "/memory", - name: "UserMemory", - component: UserMemory, - meta: { requiresAuth: true }, - }, - { - path: "/autowallet", - name: "AutoWallet", - component: AutoWallet, - meta: { requiresAuth: true }, - }, -]; - -const router = createRouter({ - history: createWebHashHistory(), - routes, -}); - -// Navigation guard pour l'authentification -router.beforeEach((to, from, next) => { - // Vérifier si la route nécessite une authentification - if (to.meta.requiresAuth) { - // Vérifier si l'utilisateur est authentifié - if (store.getters.isAuthenticated) { - next(); // L'utilisateur est authentifié, continuer - } else { - // L'utilisateur n'est pas authentifié, rediriger vers l'accueil - next({ - path: "/", - query: { - redirect: to.fullPath, - authRequired: "true", - }, - }); - } - } else { - next(); // La route ne nécessite pas d'authentification - } -}); - -export default router; diff --git a/crypto-pilot-builder/src/pipeline_agent/services/apiService.js b/crypto-pilot-builder/src/pipeline_agent/services/apiService.js deleted file mode 100644 index 979ab6f..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/services/apiService.js +++ /dev/null @@ -1,208 +0,0 @@ -/** - * Service API pour l'application CryptoPilot-Builder - */ - -const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:5000"; - -class ApiService { - constructor() { - this.baseURL = API_BASE_URL; - } - - // Méthode utilitaire pour faire des requêtes - async request(endpoint, options = {}) { - const token = localStorage.getItem("auth_token"); - - const defaultHeaders = { - "Content-Type": "application/json", - }; - - if (token) { - defaultHeaders.Authorization = `Bearer ${token}`; - } - - const config = { - method: "GET", - headers: { - ...defaultHeaders, - ...options.headers, - }, - ...options, - }; - - if (config.body && typeof config.body === "object") { - config.body = JSON.stringify(config.body); - } - - try { - const response = await fetch(`${this.baseURL}${endpoint}`, config); - - if (!response.ok) { - const errorData = await response - .json() - .catch(() => ({ error: "Erreur réseau" })); - throw new Error(errorData.error || `Erreur HTTP ${response.status}`); - } - - return await response.json(); - } catch (error) { - console.error(`Erreur API ${endpoint}:`, error); - throw error; - } - } - - // ===== AUTHENTIFICATION ===== - - async register(userData) { - return this.request("/register", { - method: "POST", - body: userData, - }); - } - - async login(credentials) { - return this.request("/login", { - method: "POST", - body: credentials, - }); - } - - // ===== CONFIGURATION AGENT ===== - - async getAgentConfig() { - return this.request("/agent-config"); - } - - async saveAgentConfig(config) { - return this.request("/agent-config", { - method: "POST", - body: config, - }); - } - - async updatePartialConfig(partialConfig) { - return this.request("/agent-config/partial", { - method: "PUT", - body: partialConfig, - }); - } - - async listAgentConfigs() { - return this.request("/agent-configs"); - } - - // ===== CHAT ===== - - async sendChatMessage(message, sessionId = null) { - return this.request("/chat", { - method: "POST", - body: { - message, - session_id: sessionId, - }, - }); - } - - async renameSession(sessionId, newName) { - return this.request(`/sessions/${sessionId}/rename`, { - method: "PUT", - body: { session_name: newName }, - }); - } - - async createNewSession(sessionName = "New Chat") { - return this.request("/new-session", { - method: "POST", - body: { session_name: sessionName }, - }); - } - - async getSession(sessionId) { - return this.request(`/sessions/${sessionId}`); - } - - async listSessions() { - return this.request("/sessions"); - } - - async deleteSession(sessionId) { - return this.request(`/sessions/${sessionId}`, { - method: "DELETE", - }); - } - - // ===== MCP ===== - - async connectMCP() { - return this.request("/mcp/connect", { - method: "POST", - }); - } - - async listMCPTools() { - return this.request("/mcp/tools"); - } - - async getCryptoPrice(cryptoId, currency = "usd") { - return this.request("/crypto/price", { - method: "POST", - body: { - crypto_id: cryptoId, - currency, - }, - }); - } - - // ===== HEALTH ===== - - async healthCheck() { - return this.request("/health"); - } - - // ===== MÉMOIRE UTILISATEUR ===== - - async getUserMemory() { - return this.request("/user-memory"); - } - - async addUserMemory(memoryData) { - return this.request("/user-memory", { - method: "POST", - body: memoryData, - }); - } - - async deleteUserMemory(memoryId) { - return this.request(`/user-memory/${memoryId}`, { - method: "DELETE", - }); - } -} - -// Instance singleton -const apiService = new ApiService(); - -export default apiService; - -// Export des méthodes pour utilisation directe -export const { - register, - login, - getAgentConfig, - saveAgentConfig, - updatePartialConfig, - listAgentConfigs, - sendChatMessage, - createNewSession, - getSession, - listSessions, - deleteSession, - connectMCP, - listMCPTools, - getCryptoPrice, - healthCheck, - getUserMemory, - addUserMemory, - renameSession, - deleteUserMemory, -} = apiService; diff --git a/crypto-pilot-builder/src/pipeline_agent/services/cryptoService.js b/crypto-pilot-builder/src/pipeline_agent/services/cryptoService.js deleted file mode 100644 index 0cd7d3d..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/services/cryptoService.js +++ /dev/null @@ -1,503 +0,0 @@ -class CryptoService { - constructor() { - this.baseURL = "https://api.coingecko.com/api/v3"; - } - - async getTopCryptos(limit = 10) { - try { - const response = await fetch( - `${this.baseURL}/coins/markets?vs_currency=usd&order=market_cap_desc&per_page=${limit}&page=1&sparkline=true&price_change_percentage=24h,7d` - ); - return await response.json(); - } catch (error) { - console.error("Erreur lors de la récupération des cryptos:", error); - return []; - } - } - - async getCryptoDetails(id) { - try { - const response = await fetch(`${this.baseURL}/coins/${id}`); - return await response.json(); - } catch (error) { - console.error( - `Erreur lors de la récupération des détails pour ${id}:`, - error - ); - return null; - } - } - - async getGlobalStats() { - try { - const response = await fetch(`${this.baseURL}/global`); - const data = await response.json(); - return data.data; - } catch (error) { - console.error( - "Erreur lors de la récupération des stats globales:", - error - ); - return null; - } - } - - async getTrendingCoins() { - try { - const response = await fetch(`${this.baseURL}/search/trending`); - const data = await response.json(); - - if (data && data.coins && Array.isArray(data.coins)) { - return data; - } - - // Si la structure n'est pas comme attendue, retourner le fallback - return this.getTrendingFallback(); - } catch (error) { - console.error( - "Erreur lors de la récupération des coins trending:", - error - ); - return this.getTrendingFallback(); - } - } - - getTrendingFallback() { - return { - coins: [ - { - item: { - id: "bitcoin", - name: "Bitcoin", - symbol: "BTC", - market_cap_rank: 1, - thumb: - "https://assets.coingecko.com/coins/images/1/thumb/bitcoin.png", - small: - "https://assets.coingecko.com/coins/images/1/small/bitcoin.png", - large: - "https://assets.coingecko.com/coins/images/1/large/bitcoin.png", - }, - }, - { - item: { - id: "ethereum", - name: "Ethereum", - symbol: "ETH", - market_cap_rank: 2, - thumb: - "https://assets.coingecko.com/coins/images/279/thumb/ethereum.png", - small: - "https://assets.coingecko.com/coins/images/279/small/ethereum.png", - large: - "https://assets.coingecko.com/coins/images/279/large/ethereum.png", - }, - }, - { - item: { - id: "binancecoin", - name: "BNB", - symbol: "BNB", - market_cap_rank: 3, - thumb: - "https://assets.coingecko.com/coins/images/825/thumb/bnb-icon2_2x.png", - small: - "https://assets.coingecko.com/coins/images/825/small/bnb-icon2_2x.png", - large: - "https://assets.coingecko.com/coins/images/825/large/bnb-icon2_2x.png", - }, - }, - { - item: { - id: "solana", - name: "Solana", - symbol: "SOL", - market_cap_rank: 4, - thumb: - "https://assets.coingecko.com/coins/images/4128/thumb/solana.png", - small: - "https://assets.coingecko.com/coins/images/4128/small/solana.png", - large: - "https://assets.coingecko.com/coins/images/4128/large/solana.png", - }, - }, - { - item: { - id: "ripple", - name: "XRP", - symbol: "XRP", - market_cap_rank: 5, - thumb: - "https://assets.coingecko.com/coins/images/44/thumb/xrp-symbol-white-128.png", - small: - "https://assets.coingecko.com/coins/images/44/small/xrp-symbol-white-128.png", - large: - "https://assets.coingecko.com/coins/images/44/large/xrp-symbol-white-128.png", - }, - }, - { - item: { - id: "cardano", - name: "Cardano", - symbol: "ADA", - market_cap_rank: 6, - thumb: - "https://assets.coingecko.com/coins/images/975/thumb/cardano.png", - small: - "https://assets.coingecko.com/coins/images/975/small/cardano.png", - large: - "https://assets.coingecko.com/coins/images/975/large/cardano.png", - }, - }, - { - item: { - id: "dogecoin", - name: "Dogecoin", - symbol: "DOGE", - market_cap_rank: 7, - thumb: - "https://assets.coingecko.com/coins/images/5/thumb/dogecoin.png", - small: - "https://assets.coingecko.com/coins/images/5/small/dogecoin.png", - large: - "https://assets.coingecko.com/coins/images/5/large/dogecoin.png", - }, - }, - { - item: { - id: "avalanche-2", - name: "Avalanche", - symbol: "AVAX", - market_cap_rank: 8, - thumb: - "https://assets.coingecko.com/coins/images/12559/thumb/Avalanche_Circle_RedWhite_Trans.png", - small: - "https://assets.coingecko.com/coins/images/12559/small/Avalanche_Circle_RedWhite_Trans.png", - large: - "https://assets.coingecko.com/coins/images/12559/large/Avalanche_Circle_RedWhite_Trans.png", - }, - }, - { - item: { - id: "polkadot", - name: "Polkadot", - symbol: "DOT", - market_cap_rank: 9, - thumb: - "https://assets.coingecko.com/coins/images/12171/thumb/polkadot.png", - small: - "https://assets.coingecko.com/coins/images/12171/small/polkadot.png", - large: - "https://assets.coingecko.com/coins/images/12171/large/polkadot.png", - }, - }, - { - item: { - id: "chainlink", - name: "Chainlink", - symbol: "LINK", - market_cap_rank: 10, - thumb: - "https://assets.coingecko.com/coins/images/877/thumb/chainlink-new-logo.png", - small: - "https://assets.coingecko.com/coins/images/877/small/chainlink-new-logo.png", - large: - "https://assets.coingecko.com/coins/images/877/large/chainlink-new-logo.png", - }, - }, - ], - }; - } - - async getCryptoNews() { - try { - // Utilisation de l'API CryptoCompare pour récupérer de vraies actualités crypto - const response = await fetch( - "https://min-api.cryptocompare.com/data/v2/news/?lang=EN&limit=20" - ); - const data = await response.json(); - - if (data.Data && Array.isArray(data.Data)) { - return data.Data.map((article) => ({ - title: article.title, - source: article.source_info - ? article.source_info.name - : "CryptoCompare", - time: this.formatTimeAgo(article.published_on), - url: article.url, - categories: article.categories || "General", - lang: article.lang || "EN", - body: article.body || "", - })); - } - - return []; - } catch (error) { - console.error( - "Erreur lors de la récupération des actualités crypto:", - error - ); - // Fallback en cas d'erreur API - return [ - { - title: "Bitcoin atteint de nouveaux sommets historiques", - source: "CoinTelegraph", - time: "2h", - url: "https://cointelegraph.com/news/bitcoin-reaches-new-all-time-high", - categories: "Bitcoin", - body: "Bitcoin continue sa progression avec de nouveaux records...", - }, - { - title: "Ethereum 2.0 : La mise à jour révolutionnaire", - source: "CoinDesk", - time: "4h", - url: "https://coindesk.com/news/ethereum-2-0-revolutionary-update", - categories: "Ethereum", - body: "Ethereum lance sa mise à jour majeure...", - }, - { - title: "Nouvelle réglementation DeFi en Europe", - source: "DeFi Pulse", - time: "6h", - url: "https://defipulse.com/blog/new-defi-regulation-europe", - categories: "DeFi", - body: "L'Europe annonce de nouvelles règles pour la DeFi...", - }, - ]; - } - } - - async getPersonalizedNews(cryptoName) { - try { - console.log("🔍 Recherche de nouvelles personnalisées pour:", cryptoName); - - // Récupérer toutes les nouvelles - const allNews = await this.getCryptoNews(); - - if (!allNews || allNews.length === 0) { - console.log("⚠️ Aucune nouvelle disponible, utilisation du fallback"); - return this.getPersonalizedNewsFallback(cryptoName); - } - - // Créer des mots-clés de recherche pour la crypto - const searchKeywords = this.generateSearchKeywords(cryptoName); - console.log("🔑 Mots-clés de recherche:", searchKeywords); - - // Filtrer les nouvelles par mots-clés - const personalizedNews = allNews.filter((article) => { - const searchText = - `${article.title} ${article.body} ${article.categories}`.toLowerCase(); - return searchKeywords.some((keyword) => - searchText.includes(keyword.toLowerCase()) - ); - }); - - console.log( - `📰 Trouvé ${personalizedNews.length} nouvelles personnalisées sur ${allNews.length} totales` - ); - - // Si pas assez de nouvelles personnalisées, ajouter des nouvelles générales - if (personalizedNews.length < 4) { - const remainingSlots = 4 - personalizedNews.length; - const generalNews = allNews - .filter((article) => !personalizedNews.includes(article)) - .slice(0, remainingSlots); - - personalizedNews.push(...generalNews); - console.log(`➕ Ajouté ${generalNews.length} nouvelles générales`); - } - - // Limiter à 4 nouvelles maximum - return personalizedNews.slice(0, 4); - } catch (error) { - console.error( - "❌ Erreur lors de la récupération des nouvelles personnalisées:", - error - ); - return this.getPersonalizedNewsFallback(cryptoName); - } - } - - generateSearchKeywords(cryptoName) { - // Mapping des noms de crypto vers des mots-clés de recherche - const keywordMapping = { - bitcoin: [ - "bitcoin", - "btc", - "bitcoin price", - "bitcoin news", - "crypto king", - ], - ethereum: [ - "ethereum", - "eth", - "ethereum price", - "ethereum news", - "defi", - "smart contracts", - ], - solana: [ - "solana", - "sol", - "solana price", - "solana news", - "fast blockchain", - ], - cardano: [ - "cardano", - "ada", - "cardano price", - "cardano news", - "proof of stake", - ], - polkadot: [ - "polkadot", - "dot", - "polkadot price", - "polkadot news", - "parachain", - ], - avalanche: [ - "avalanche", - "avax", - "avalanche price", - "avalanche news", - "subnet", - ], - chainlink: [ - "chainlink", - "link", - "chainlink price", - "chainlink news", - "oracle", - ], - ripple: ["ripple", "xrp", "ripple price", "ripple news", "xrp ledger"], - binance: [ - "binance", - "bnb", - "binance coin", - "binance price", - "binance news", - ], - dogecoin: [ - "dogecoin", - "doge", - "dogecoin price", - "dogecoin news", - "meme coin", - ], - }; - - const normalizedName = cryptoName.toLowerCase(); - - // Chercher dans le mapping - for (const [key, keywords] of Object.entries(keywordMapping)) { - if (normalizedName.includes(key) || key.includes(normalizedName)) { - return keywords; - } - } - - // Fallback : utiliser le nom de la crypto et des mots-clés génériques - return [ - cryptoName.toLowerCase(), - cryptoName, - cryptoName.toUpperCase(), - "crypto", - "blockchain", - "digital currency", - ]; - } - - getPersonalizedNewsFallback(cryptoName) { - // Fallback avec des nouvelles simulées si l'API échoue - const cryptoDisplayName = - cryptoName.charAt(0).toUpperCase() + cryptoName.slice(1); - - return [ - { - title: `${cryptoDisplayName} : Nouvelles avancées technologiques et adoption croissante`, - source: "CryptoDaily", - time: "1h", - url: "#", - categories: cryptoDisplayName, - body: `Les dernières nouvelles sur ${cryptoDisplayName} montrent une adoption croissante...`, - }, - { - title: `Développements majeurs pour ${cryptoDisplayName} : Mise à jour du protocole`, - source: "CoinDesk", - time: "3h", - url: "#", - categories: cryptoDisplayName, - body: `${cryptoDisplayName} annonce de nouveaux développements majeurs...`, - }, - { - title: `Analyse technique : ${cryptoDisplayName} en 2024 - Perspectives et tendances`, - source: "The Block", - time: "5h", - url: "#", - categories: cryptoDisplayName, - body: `Analyse approfondie des perspectives pour ${cryptoDisplayName}...`, - }, - { - title: `Écosystème ${cryptoDisplayName} : Nouveaux partenariats et intégrations`, - source: "CryptoNews", - time: "8h", - url: "#", - categories: cryptoDisplayName, - body: `L'écosystème ${cryptoDisplayName} continue de s'étendre...`, - }, - ]; - } - - formatTimeAgo(timestamp) { - const now = Math.floor(Date.now() / 1000); - const diff = now - timestamp; - - if (diff < 3600) { - const minutes = Math.floor(diff / 60); - return `${minutes}min`; - } else if (diff < 86400) { - const hours = Math.floor(diff / 3600); - return `${hours}h`; - } else { - const days = Math.floor(diff / 86400); - return `${days}j`; - } - } - - formatPrice(price) { - if (price >= 1) { - return new Intl.NumberFormat("fr-FR", { - style: "currency", - currency: "USD", - minimumFractionDigits: 2, - maximumFractionDigits: 2, - }).format(price); - } else { - return new Intl.NumberFormat("fr-FR", { - style: "currency", - currency: "USD", - minimumFractionDigits: 4, - maximumFractionDigits: 6, - }).format(price); - } - } - - formatPercentage(percentage) { - return `${percentage >= 0 ? "+" : ""}${percentage.toFixed(2)}%`; - } - - formatMarketCap(marketCap) { - if (marketCap >= 1e12) { - return `${(marketCap / 1e12).toFixed(2)}T $`; - } else if (marketCap >= 1e9) { - return `${(marketCap / 1e9).toFixed(2)}B $`; - } else if (marketCap >= 1e6) { - return `${(marketCap / 1e6).toFixed(2)}M $`; - } else { - return `${marketCap.toFixed(0)} $`; - } - } -} - -export default new CryptoService(); diff --git a/crypto-pilot-builder/src/pipeline_agent/store/index.js b/crypto-pilot-builder/src/pipeline_agent/store/index.js deleted file mode 100644 index c7f92b6..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/store/index.js +++ /dev/null @@ -1,464 +0,0 @@ -import { createStore } from "vuex"; -import apiService from "../services/apiService"; - -// Fonction de fallback pour le localStorage (en cas d'absence de connexion) -const loadFromStorage = () => { - try { - const saved = localStorage.getItem("aiConfig"); - return saved - ? JSON.parse(saved) - : { selectedModel: "", apiKey: "", prompt: "", modules: {} }; - } catch (error) { - console.error("Erreur lors du chargement des données:", error); - return { selectedModel: "", apiKey: "", prompt: "", modules: {} }; - } -}; - -const saveToStorage = (config) => { - try { - localStorage.setItem("aiConfig", JSON.stringify(config)); - } catch (error) { - console.error("Erreur lors de la sauvegarde:", error); - } -}; - -export default createStore({ - modules: { - auth: { - namespaced: true, - state: { - isAuthenticated: !!localStorage.getItem("auth_token"), - user: null, - token: localStorage.getItem("auth_token"), - loading: false, - error: null, - }, - - mutations: { - SET_LOADING(state, loading) { - state.loading = loading; - }, - - SET_ERROR(state, error) { - state.error = error; - }, - - SET_AUTH(state, { user, token }) { - state.isAuthenticated = true; - state.user = user; - state.token = token; - if (token) { - localStorage.setItem("auth_token", token); - } - }, - - CLEAR_AUTH(state) { - state.isAuthenticated = false; - state.user = null; - state.token = null; - localStorage.removeItem("auth_token"); - }, - }, - - actions: { - async login({ commit }, { email, password }) { - try { - commit("SET_LOADING", true); - commit("SET_ERROR", null); - - const response = await apiService.login({ email, password }); - - commit("SET_AUTH", { - user: response.user, - token: response.access_token, - }); - - // Charger la configuration après connexion - await this.dispatch("loadAgentConfig"); - - return response; - } catch (error) { - commit( - "SET_ERROR", - error.response?.data?.error || "Erreur de connexion" - ); - throw error; - } finally { - commit("SET_LOADING", false); - } - }, - - async renameChat({ commit }, { chatId, newName }) { - try { - await apiService.renameSession(chatId, newName); - commit("SET_CHAT_NAME", { chatId, newName }); - } catch (error) { - console.error("Erreur lors du renommage du chat:", error); - // Optionnel : afficher une notification à l'utilisateur - } - }, - async register({ commit }, { username, email, password }) { - try { - commit("SET_LOADING", true); - commit("SET_ERROR", null); - - const response = await apiService.register({ - username, - email, - password, - }); - - commit("SET_AUTH", { - user: response.user, - token: response.access_token, - }); - - return response; - } catch (error) { - commit( - "SET_ERROR", - error.response?.data?.error || "Erreur d'inscription" - ); - throw error; - } finally { - commit("SET_LOADING", false); - } - }, - - logout({ commit }) { - commit("CLEAR_AUTH"); - this.dispatch("clearConfig"); - }, - - checkAuth({ commit, state }) { - const token = localStorage.getItem("auth_token"); - if (token && !state.isAuthenticated) { - // Tenter de valider le token avec l'API si nécessaire - commit("SET_AUTH", { user: null, token }); - } - }, - }, - - getters: { - isAuthenticated: (state) => state.isAuthenticated, - user: (state) => state.user, - authLoading: (state) => state.loading, - authError: (state) => state.error, - }, - } - }, - - state: { - aiConfig: loadFromStorage(), - loading: false, - error: null, - // Ajout de l'état pour les chats - chats: [], - activeChat: null, - nextChatId: 1 - }, - - mutations: { - SET_LOADING(state, loading) { - state.loading = loading; - }, - - SET_ERROR(state, error) { - state.error = error; - }, - - SET_AI_CONFIG(state, config) { - state.aiConfig = { ...state.aiConfig, ...config }; - saveToStorage(state.aiConfig); // Sauvegarde locale de secours - }, - - SET_API_KEY(state, apiKey) { - state.aiConfig.apiKey = apiKey; - saveToStorage(state.aiConfig); - }, - - SET_MODEL(state, model) { - state.aiConfig.selectedModel = model; - saveToStorage(state.aiConfig); - }, - - SET_PROMPT(state, prompt) { - state.aiConfig.prompt = prompt; - saveToStorage(state.aiConfig); - }, - - SET_MODULES(state, modules) { - state.aiConfig.modules = modules; - saveToStorage(state.aiConfig); - }, - SET_CHAT_NAME(state, { chatId, newName }) { - const chat = state.chats.find(c => c.id === chatId); - if (chat) { - chat.name = newName; - } - }, - CLEAR_CONFIG(state) { - state.aiConfig = { - selectedModel: "", - apiKey: "", - prompt: "", - modules: {}, - }; - localStorage.removeItem("aiConfig"); - }, - - // Mutations pour la gestion des chats - SET_CHATS(state, chats) { - state.chats = chats; - // Mettre à jour nextChatId basé sur les IDs existants - state.nextChatId = chats.length > 0 - ? Math.max(...chats.map(c => c.id)) + 1 - : 1; - }, - - ADD_CHAT(state, chat) { - state.chats.push(chat); - state.activeChat = chat.id; - }, - - DELETE_CHAT(state, chatId) { - const index = state.chats.findIndex(chat => chat.id === chatId); - if (index !== -1) { - state.chats.splice(index, 1); - // Si le chat actif est supprimé, sélectionner le premier chat - if (state.activeChat === chatId && state.chats.length > 0) { - state.activeChat = state.chats[0].id; - } - } - } - }, - - actions: { - // Actions de configuration avec API - async loadAgentConfig({ commit, rootState }) { - if (!rootState.auth.isAuthenticated) { - console.warn( - "Utilisateur non authentifié, utilisation du localStorage" - ); - return; - } - - try { - commit("SET_LOADING", true); - commit("SET_ERROR", null); - - const response = await apiService.getAgentConfig(); - commit("SET_AI_CONFIG", { - selectedModel: response.config.selectedModel, - apiKey: response.config.apiKey, - prompt: response.config.prompt, - modules: response.config.modules || {}, - }); - } catch (error) { - console.error( - "Erreur lors du chargement de la configuration:", - error.message - ); - commit("SET_ERROR", error.message); - // En cas d'erreur, garder les données locales - } finally { - commit("SET_LOADING", false); - } - }, - - // Nouvelle action pour charger les chats depuis l'API - async loadChatsFromApi({ commit }) { - try { - commit("SET_LOADING", true); - const response = await apiService.listSessions(); - const sessions = response.sessions || []; - - // Convertir les sessions en format compatible avec l'UI - const chats = sessions.map(session => ({ - id: session.session_id, - name: session.session_name || `Chat ${session.session_id}` - })); - - commit("SET_CHATS", chats); - } catch (error) { - console.error("Erreur lors du chargement des chats:", error); - // Fallback avec un chat par défaut - commit("SET_CHATS", [{ - id: 1, - name: "Chat par défaut" - }]); - } finally { - commit("SET_LOADING", false); - } - }, - - // Nouvelle action pour créer un chat - async createNewChat({ commit, state }, chatName) { - try { - commit("SET_LOADING", true); - const sessionData = await apiService.createNewSession(chatName); - - const newChat = { - id: sessionData.session_id, - name: chatName - }; - - commit("ADD_CHAT", newChat); - return newChat; - } catch (error) { - console.error("Erreur lors de la création du chat:", error); - // Créer un chat local en fallback - const fallbackChat = { - id: state.nextChatId, - name: chatName - }; - commit("ADD_CHAT", fallbackChat); - return fallbackChat; - } finally { - commit("SET_LOADING", false); - } - }, - - // Nouvelle action pour supprimer un chat - async deleteChat({ commit }, chatId) { - try { - commit("SET_LOADING", true); - await apiService.deleteSession(chatId); - commit("DELETE_CHAT", chatId); - } catch (error) { - console.error("Erreur lors de la suppression du chat:", error); - // Suppression locale en fallback - commit("DELETE_CHAT", chatId); - } finally { - commit("SET_LOADING", false); - } - }, - - async saveCompleteConfig({ commit, rootState }, config) { - if (!rootState.auth.isAuthenticated) { - // Mode hors ligne - sauvegarde locale uniquement - commit("SET_AI_CONFIG", config); - return; - } - - try { - commit("SET_LOADING", true); - commit("SET_ERROR", null); - - const response = await apiService.saveAgentConfig(config); - commit("SET_AI_CONFIG", { - selectedModel: response.config.selectedModel, - apiKey: response.config.apiKey, - prompt: response.config.prompt, - modules: response.config.modules || {}, - }); - - return response; - } catch (error) { - console.error("Erreur lors de la sauvegarde complète:", error.message); - commit("SET_ERROR", error.message); - // Sauvegarde locale de secours - commit("SET_AI_CONFIG", config); - throw error; - } finally { - commit("SET_LOADING", false); - } - }, - - async updateAIConfig({ commit, rootState }, config) { - // Mise à jour locale immédiate pour la réactivité - commit("SET_AI_CONFIG", config); - - if (!rootState.auth.isAuthenticated) { - return; - } - - try { - // Sauvegarde en arrière-plan via API - await apiService.updatePartialConfig(config); - } catch (error) { - console.error( - "Erreur lors de la mise à jour partielle:", - error.message - ); - // Pas de throw - la mise à jour locale est déjà faite - } - }, - - async setApiKey({ commit, rootState }, apiKey) { - commit("SET_API_KEY", apiKey); - - if (rootState.auth.isAuthenticated) { - try { - await apiService.updatePartialConfig({ apiKey }); - } catch (error) { - console.error( - "Erreur lors de la sauvegarde de la clé API:", - error.message - ); - } - } - }, - - async setModel({ commit, rootState }, model) { - commit("SET_MODEL", model); - - if (rootState.auth.isAuthenticated) { - try { - await apiService.updatePartialConfig({ selectedModel: model }); - } catch (error) { - console.error( - "Erreur lors de la sauvegarde du modèle:", - error.message - ); - } - } - }, - - async setPrompt({ commit, rootState }, prompt) { - commit("SET_PROMPT", prompt); - - if (rootState.auth.isAuthenticated) { - try { - await apiService.updatePartialConfig({ prompt }); - } catch (error) { - console.error( - "Erreur lors de la sauvegarde du prompt:", - error.message - ); - } - } - }, - - async setModules({ commit, rootState }, modules) { - commit("SET_MODULES", modules); - - if (rootState.auth.isAuthenticated) { - try { - await apiService.updatePartialConfig({ modules }); - } catch (error) { - console.error( - "Erreur lors de la sauvegarde des modules:", - error.message - ); - } - } - }, - - clearConfig({ commit }) { - commit("CLEAR_CONFIG"); - } - }, - - getters: { - aiConfig: (state) => state.aiConfig, - isLoading: (state) => state.loading, - error: (state) => state.error, - isAuthenticated: (state, getters, rootState) => - rootState.auth.isAuthenticated, - user: (state, getters, rootState) => rootState.auth.user, - chats: (state) => state.chats, - activeChat: (state) => state.activeChat, - nextChatId: (state) => state.nextChatId - } -}); \ No newline at end of file diff --git a/crypto-pilot-builder/src/pipeline_agent/tests/setup.js b/crypto-pilot-builder/src/pipeline_agent/tests/setup.js deleted file mode 100644 index d64b6f8..0000000 --- a/crypto-pilot-builder/src/pipeline_agent/tests/setup.js +++ /dev/null @@ -1,21 +0,0 @@ -// src/test/setup.js -import { vi } from 'vitest' - -// Mock du fetch global -global.fetch = vi.fn() - -// Mock de console pour éviter les logs pendant les tests -global.console = { - ...console, - log: vi.fn(), - error: vi.fn(), - warn: vi.fn(), -} - -// Mock de l'objet window si nécessaire -Object.defineProperty(window, 'location', { - value: { - href: 'http://localhost:3000', - }, - writable: true, -}) \ No newline at end of file diff --git a/crypto-pilot-builder/src/router/index.js b/crypto-pilot-builder/src/router/index.js index af2f9b4..2f84e1b 100644 --- a/crypto-pilot-builder/src/router/index.js +++ b/crypto-pilot-builder/src/router/index.js @@ -1,7 +1,6 @@ import { createRouter, createWebHashHistory } from "vue-router"; import Accueil from "../acceuil/Accueil.vue"; import AI from "../agent_building/Ai.vue"; -import Module from "../agent_building/Module.vue"; import Prompte from "../agent_building/Prompte.vue"; import ChatPage from "../acceuil/Chat_Page.vue"; import UserMemory from "../components/UserMemory.vue"; @@ -27,9 +26,7 @@ const routes = [ }, { path: "/Module", - name: "Module", - component: Module, - meta: { requiresAuth: true }, + redirect: "/Prompte", }, { path: "/Prompte", diff --git a/crypto-pilot-builder/src/services/apiService.js b/crypto-pilot-builder/src/services/apiService.js index 9a05627..3a6b9d5 100644 --- a/crypto-pilot-builder/src/services/apiService.js +++ b/crypto-pilot-builder/src/services/apiService.js @@ -267,6 +267,18 @@ class ApiService { method: "POST", }); } + + // ===== MCP TOOLS ===== + + async callMCPTool(toolName, parameters = {}) { + return this.request("/mcp/call-tool", { + method: "POST", + body: { + tool_name: toolName, + parameters, + }, + }); + } } // Instance singleton @@ -309,4 +321,5 @@ export const { stopPipeline, startAllAgents, stopAllAgents, + callMCPTool, } = apiService; diff --git a/init.sql b/init.sql index ca41a2f..b4481fe 100644 --- a/init.sql +++ b/init.sql @@ -28,6 +28,7 @@ CREATE TABLE IF NOT EXISTS chat_messages ( CREATE TABLE IF NOT EXISTS agent_configs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), user_id UUID REFERENCES users(id) ON DELETE CASCADE, + provider VARCHAR(50) NOT NULL DEFAULT 'openai', selected_model VARCHAR(100) NOT NULL, api_key TEXT NOT NULL, modules_config JSON,