S
c
R
a
P
e
Edit Snippet
Perbarui kode snippet Anda
Judul File
Bahasa
JavaScript
Python
HTML
CSS
JSON
SQL
Bash/Terminal
TypeScript
PHP
Java
Go
Rust
Deskripsi Singkat
(Opsional)
AI assistant real-time with multi-modal support.
Tags
(Pisahkan dengan koma)
Kode
*
/*** @ Base: https://app.khoj.dev/ @ Author: Shannz @ Note: AI assistant real-time with multi-modal support. ***/ import axios from 'axios'; import { wrapper } from 'axios-cookiejar-support'; import { CookieJar } from 'tough-cookie'; import WebSocket from 'ws'; import fs from 'fs'; import path from 'path'; import mime from 'mime-types'; import FormData from 'form-data'; const CONFIG = { BASE_URL: "https://app.khoj.dev", API: { SESSION: "/api/chat/sessions", WS: "wss://app.khoj.dev/api/chat/ws", CONVERT: "/api/content/convert" }, DEFAULT_COOKIE: 'PASTE_COOKIE_DISINI', HEADERS: { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36", "Origin": "https://app.khoj.dev", "Referer": "https://app.khoj.dev/" }, CLIENT_PARAMS: { client: "web", agent_slug: "khoj" } }; const createClient = (cookieStr) => { const jar = new CookieJar(); if (cookieStr) { jar.setCookieSync(cookieStr, CONFIG.BASE_URL); } return wrapper(axios.create({ jar })); }; const fileUtils = { processImages: (imagePaths) => { const images = []; for (const filePath of imagePaths) { if (fs.existsSync(filePath)) { const fileBuffer = fs.readFileSync(filePath); const mimeType = mime.lookup(filePath) || 'image/jpeg'; const base64 = fileBuffer.toString('base64'); images.push(`data:${mimeType};base64,${base64}`); } else { console.warn(`[Warn] Gambar tidak ditemukan: ${filePath}`); } } return images; }, processFiles: async (filePaths, client) => { if (!filePaths || filePaths.length === 0) return []; try { const form = new FormData(); let validFiles = 0; for (const filePath of filePaths) { if (fs.existsSync(filePath)) { form.append('files', fs.createReadStream(filePath)); validFiles++; } else { console.warn(`[Warn] File tidak ditemukan: ${filePath}`); } } if (validFiles === 0) return []; const res = await client.post(CONFIG.BASE_URL + CONFIG.API.CONVERT, form, { headers: { ...CONFIG.HEADERS, ...form.getHeaders() } }); return res.data; } catch (error) { console.error(`[Error] Gagal convert file: ${error.message}`); return []; } } }; export const khoj = { chat: async (query, options = {}) => { const { chatId: initialChatId = null, cookie = CONFIG.DEFAULT_COOKIE, images = [], files = [] } = options; return new Promise(async (resolve, reject) => { const client = createClient(cookie); let chatId = initialChatId; let finalResult = { chatId: chatId, query: query, answer: "", tools: [], searchQueries: [], sources: [], debug: { images_sent: 0, files_sent: 0 } }; let safetyTimer; try { if (!chatId) { try { const sessionRes = await client.post( `${CONFIG.BASE_URL}${CONFIG.API.SESSION}`, {}, { params: CONFIG.CLIENT_PARAMS, headers: { ...CONFIG.HEADERS, 'Cookie': cookie } } ); chatId = sessionRes.data.conversation_id; finalResult.chatId = chatId; } catch (err) { return reject({ status: 'error', message: `Gagal membuat sesi: ${err.message}` }); } } const [processedImages, processedFiles] = await Promise.all([ images.length > 0 ? fileUtils.processImages(images) : [], files.length > 0 ? fileUtils.processFiles(files, client) : [] ]); finalResult.debug.images_sent = processedImages.length; finalResult.debug.files_sent = processedFiles.length; const wsUrl = `${CONFIG.API.WS}?client=web`; const ws = new WebSocket(wsUrl, { headers: { 'Cookie': cookie, 'Origin': CONFIG.BASE_URL } }); safetyTimer = setTimeout(() => { if (ws.readyState === WebSocket.OPEN) { ws.close(); reject({ status: 'timeout', message: 'No response received within 60s' }); } }, 60000); ws.on('open', () => { const payload = { "q": query, "conversation_id": chatId, "stream": true, "city": "Malang", "region": "East Java", "country": "ID", "timezone": "Asia/Jakarta" }; if (processedImages.length > 0) { payload.images = processedImages; } if (processedFiles.length > 0) { payload.files = processedFiles; } ws.send(JSON.stringify(payload)); }); ws.on('message', (rawData) => { let str = rawData.toString().trim(); str = str.replace(/␃|🔚|␗/g, "").trim(); if (!str) return; try { const json = JSON.parse(str); if (json.type === "metadata") { finalResult.chatId = json.data.conversationId; } else if (json.type === "status") { if (json.data.includes("Selected Tools:")) { const toolText = json.data.replace("**Selected Tools:** ", ""); finalResult.tools = toolText.split(", "); } if (json.data.includes("Searching the web for")) { const queries = json.data.split("\n- ").slice(1); finalResult.searchQueries = queries.map(q => q.trim()); } } else if (json.type === "references") { const onlineContext = json.data.onlineContext; if (onlineContext) { Object.values(onlineContext).forEach(val => { if (val.organic) { val.organic.forEach(item => { finalResult.sources.push({ title: item.title, url: item.link }); }); } }); } } else if (json.type === "end_response") { finalResult.answer = finalResult.answer.trim(); clearTimeout(safetyTimer); ws.close(); resolve(finalResult); } } catch (e) { if (!str.startsWith('{"type":') && !str.includes('"turnId"')) { finalResult.answer += str; } } }); ws.on('error', (err) => { clearTimeout(safetyTimer); ws.close(); reject({ status: 'error', message: `WebSocket Error: ${err.message}` }); }); ws.on('close', () => { clearTimeout(safetyTimer); }); } catch (error) { clearTimeout(safetyTimer); reject({ status: 'error', message: `Fatal Error: ${error.message}` }); } }); } }; /*(async () => { try { console.log("Mengirim request..."); // Contoh: Kirim Text + Gambar + File Code const result = await khoj.chat("gambar apa ini? dan apa fungsi file ini?", { images: ['./orang.jpg'], files: ['./script.py'] }); console.log(result); } catch (error) { console.error("Error:", error); } })();*/
Monospace
Kunci Admin
*
Update Kode
Batal