Spaces:
Paused
Paused
| /** | |
| * M5 JavaScript SDK | |
| */ | |
| class M5Client { | |
| constructor(apiKey, baseUrl = 'https://m5.hf.space') { | |
| this.apiKey = apiKey; | |
| this.baseUrl = baseUrl.replace(/\/$/, ''); | |
| this.headers = { | |
| 'Authorization': `Bearer ${apiKey}`, | |
| 'Content-Type': 'application/json' | |
| }; | |
| } | |
| async chatCompletion(options) { | |
| const { | |
| model, | |
| messages, | |
| temperature = 0.7, | |
| maxTokens = null, | |
| stream = false, | |
| ollamaUrl = null | |
| } = options; | |
| const payload = { | |
| model, | |
| messages, | |
| temperature, | |
| stream | |
| }; | |
| if (maxTokens) payload.max_tokens = maxTokens; | |
| if (ollamaUrl) payload.ollama_url = ollamaUrl; | |
| const response = await fetch(`${this.baseUrl}/v1/chat/completions`, { | |
| method: 'POST', | |
| headers: this.headers, | |
| body: JSON.stringify(payload) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| return await response.json(); | |
| } | |
| async *chatCompletionStream(options) { | |
| const { | |
| model, | |
| messages, | |
| temperature = 0.7, | |
| maxTokens = null, | |
| ollamaUrl = null | |
| } = options; | |
| const payload = { | |
| model, | |
| messages, | |
| temperature, | |
| stream: true | |
| }; | |
| if (maxTokens) payload.max_tokens = maxTokens; | |
| if (ollamaUrl) payload.ollama_url = ollamaUrl; | |
| const response = await fetch(`${this.baseUrl}/v1/chat/completions`, { | |
| method: 'POST', | |
| headers: this.headers, | |
| body: JSON.stringify(payload) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const reader = response.body.getReader(); | |
| const decoder = new TextDecoder(); | |
| while (true) { | |
| const { done, value } = await reader.read(); | |
| if (done) break; | |
| const chunk = decoder.decode(value, { stream: true }); | |
| const lines = chunk.split('\n'); | |
| for (const line of lines) { | |
| if (!line.startsWith('data: ')) continue; | |
| const data = line.slice(6).trim(); | |
| if (data === '[DONE]') break; | |
| try { | |
| const parsed = JSON.parse(data); | |
| if (parsed.choices && parsed.choices[0]) { | |
| const delta = parsed.choices[0].delta; | |
| if (delta && delta.content) { | |
| yield delta.content; | |
| } | |
| } | |
| } catch (e) { | |
| // Skip invalid JSON | |
| } | |
| } | |
| } | |
| } | |
| async listModels() { | |
| const response = await fetch(`${this.baseUrl}/v1/models`, { | |
| headers: this.headers | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`HTTP error! status: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| return data.data || []; | |
| } | |
| } | |
| // Convenience classes | |
| class Chat { | |
| constructor(client) { | |
| this.client = client; | |
| } | |
| async create(options) { | |
| return await this.client.chatCompletion(options); | |
| } | |
| async *createStream(options) { | |
| yield* this.client.chatCompletionStream(options); | |
| } | |
| } | |
| class M5 { | |
| constructor(apiKey, baseUrl = 'https://m5.hf.space') { | |
| this.client = new M5Client(apiKey, baseUrl); | |
| this.chat = new Chat(this.client); | |
| } | |
| } | |
| // Export for Node.js | |
| if (typeof module !== 'undefined' && module.exports) { | |
| module.exports = { M5, M5Client, Chat }; | |
| } | |
| // Export for browser | |
| if (typeof window !== 'undefined') { | |
| window.M5 = M5; | |
| window.M5Client = M5Client; | |
| window.Chat = Chat; | |
| } | |