diff --git a/LICENSE b/LICENSE index 91d3120..c1f2b91 100644 --- a/LICENSE +++ b/LICENSE @@ -1,19 +1,20 @@ -The Samuel Public License Revision 5 (SPL-R5) - -Copyright (c) 2024 Sneed Group - -This document grants permission, without charge, to any individual acquiring a copy of the software and its associated documentation files (hereinafter referred to as the "Software"). Such individuals are authorized to engage in activities related to the Software with certain restrictions (listed below), including, but not limited to, the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. These permissions extend to persons to whom the Software is furnished, subject to compliance with the specified conditions outlined below. - -THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -In making contributions to the Software, contributors irrevocably assign, transfer, and convey all rights, titles, and interests in and to their contributions to the project owner(s). This assignment is absolute and encompasses all intellectual property rights, including, but not limited to, copyrights, patents, trademarks, and trade secrets. Contributors acknowledge and consent that they have no further claim, right, or interest in their contributions and agree to relinquish any moral rights associated with the contributed content. This assignment is effective upon the act of contributing to the Software, and contributors affirm that they have the authority to make such an assignment. However, contributors retain the right to modify their contributions. - -Furthermore, this document permits the reuse and redistribution of both executable binaries and source code, contingent upon the inclusion of the previously mentioned copyright notice and permission notice in all copies or substantial portions of the Software. It is imperative that you explicitly acknowledge and agree that the owner(s) retain ownership rights over the aforementioned source code. - -Moreover, companies using the Software are encouraged to contribute upstream. Fortune 500 companies are required to make an annual contribution of at least 20,000 USD or an equivalent amount to support the project's sustainability unless no donation option is provided. - -Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owners(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development. - -In addition, the owner of the code is granted the authority to update their copy of The Samuel Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Samuel Public License. - -The aforementioned copyright notice and this permission notice must be included in all copies or substantial portions of the Software. +The Sammy Public License Revision 5 Sub-Revision 1 (SPL-R5 SR1) + +Copyright (c) 2024 Sneed Group + +This document grants permission, without charge, to any individual acquiring a copy of the software and its associated documentation files (hereinafter referred to as the "Software"). Such individuals are authorized to engage in activities related to the Software with certain restrictions (listed below), including, but not limited to, the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software. These permissions extend to persons to whom the Software is furnished, subject to compliance with the specified conditions outlined below. + +THE SOFTWARE IS PROVIDED "AS IS," WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM, OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +In making contributions to the Software, contributors irrevocably assign, transfer, and convey all rights, titles, and interests in and to their contributions to the project owner(s). This assignment is absolute and encompasses all intellectual property rights, including, but not limited to, copyrights, patents, trademarks, and trade secrets. Contributors acknowledge and consent that they have no further claim, right, or interest in their contributions and agree to relinquish any moral rights associated with the contributed content. This assignment is effective upon the act of contributing to the Software, and contributors affirm that they have the authority to make such an assignment. However, contributors retain the right to modify their contributions. + +Furthermore, this document permits the reuse and redistribution of both executable binaries and source code, contingent upon the inclusion of the previously mentioned copyright notice and permission notice in all copies or substantial portions of the Software. It is imperative that you explicitly acknowledge and agree that the owner(s) retain ownership rights over the aforementioned source code. + +Moreover, companies using the Software are encouraged to contribute upstream. Fortune 500 companies are required to make an annual contribution of at least 20,000 USD or an equivalent amount per project used to support the said projects' sustainability unless no donation option is provided. Also, all Fortune 500 companies using said projects are required to contibute their changes upstream as well. + +Additionally, note that the use of AI-assisted tools, including but not limited to GitHub Copilot and ChatGPT, is expressly permitted in conjunction with this software. Users are encouraged to leverage these AI tools to enhance their experience in developing, modifying, and interacting with the Software. The permission granted herein extends to the integration and utilization of AI-generated content for coding and communication purposes. The owners(s) of the Software acknowledge and embrace the collaborative nature of AI-assisted development. + +In addition, the owner of the code is granted the authority to update their copy of The Samuel Public License (SPL) to the latest revision. This update may be undertaken at the discretion of the owner to ensure alignment with any subsequent revisions made to The Samuel Public License. + +The aforementioned copyright notice and this permission notice must be included in all copies or substantial portions of the Software. + diff --git a/index.mjs b/index.mjs index 3817838..b9620c4 100644 --- a/index.mjs +++ b/index.mjs @@ -1,119 +1,95 @@ -import readline from 'readline'; -import Ollama from 'ollama-js-client'; -import fs from 'fs'; +import { Ollama } from "@langchain/ollama"; +import { PuppeteerWebBaseLoader } from "@langchain/community/document_loaders/web/puppeteer"; +import * as path from 'path' +import http from 'http'; +import { URL } from 'url'; +const debugMode = false +const __dirname = path.resolve(); -let DEBUG_MODE = true; - -async function ollamaInteraction() { - const rl = await readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); - - function isUndefined(value) { - if (typeof value == undefined || value == null) { - return true; - } else { - return false; - } - } - - function ifUndefinedReturnBlankStr(value) { - if (isUndefined(value)) { - return ""; - } else { - return value; - } - } - - function ifUndefinedReturnBlankFunction(value) { - if (isUndefined(value)) { - return Function(); - } else { - return value; - } - } - - function extractFunctionName(response) { - const match = response.match(/([^<]+)<\/functioncall>/); - return match ? match[1] : ''; - } - - function generateRandomString(length = 16) { - const characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; - let result = ""; - for (let i = 0; i < length; i++) { - result += characters.charAt(Math.floor(Math.random() * characters.length)); - } - return result; - } - - // INTERNAL FUNCTIONS MAGIC BEGIN - let internalFunctions = { - jitsi: function() { - const id = generateRandomString(); - const jitsiURL = `https://meet.jit.si/${id}`; - console.log(jitsiURL); - return jitsiURL; - }, - search: function(q) { - q = q.replaceAll(" ", "+"); - const searchURL = `https://www.google.com/search?q=${q}&sca_upv=1`; - console.log(searchURL); - return searchURL; - } - }; - // END OF INTERNAL FUNCTIONS MAGIC - - return new Promise(async (resolve) => { - rl.question("User: ", async (userInput) => { - rl.close(); - - const ollama = new Ollama({ - model: "sneedgroup-llama3-agent", - url: "http://127.0.0.1:11434/api/", - }); // Ensure the model name is correct - - const responsePreParse = await ollama.prompt(userInput); - const response = responsePreParse.response; - const functionName = extractFunctionName(response).replaceAll("\n", ''); - const responseWithoutFunctionCall = await response.replace(/.*?<\/functioncall>/, ''); - - console.log(responseWithoutFunctionCall); - - let contentToAppend = `: ${userInput} - : ${responseWithoutFunctionCall}`; - - await fs.appendFile('journal.txt', contentToAppend, async (err) => { - if (err) { - await console.error(err); - } else { - await console.log('Content appended to journal file successfully!'); - } - }); - - if (DEBUG_MODE) { console.log(`DEBUG: RUN ${functionName}`); } - - // Call the function by name if it exists in internalFunctions - try { - if (DEBUG_MODE) { console.log(`DEBUG: ${functionName} => internalFunctions[${(functionName)})];`) } - internalFunctions[functionName](); - console.log("OK") - } catch (err) { - if (DEBUG_MODE) { console.log(`Error: ${err}`) } - } - - resolve(); // Resolve the promise after processing - }); +function llamaLoader(model="sparksammy/samantha-3.1", url="http://localhost:11434") { + return new Ollama({ + baseUrl: url, // Default value + model: model, // Default value }); } -(async () => { - while (true) { - try { - await ollamaInteraction(); - } catch (error) { - console.error('Error occurred:', error); - } +const ollama = llamaLoader() + + + +async function loadDoc(www) { + try { + const loader = new PuppeteerWebBaseLoader(String(www), { + launchOptions: { + headless: true, + }, + gotoOptions: { + waitUntil: "domcontentloaded", + }, + }); + + const docs = await loader.load(); + return docs[0].pageContent; + } catch { + return "" } -})(); +} + +async function getReply(q, www='docChatterThing.testfile.invalid') { + let document + let query + if (www == "docChatterThing.testfile.invalid" || www == "") { + document = "Chatting." + } else { + document = await loadDoc(www) + } + + query = String(`Context: ${document} Query: ${q}`) + + if (debugMode) { + console.log(query) //Debug feature that prints out the user's query. + } + + const stream = await ollama.stream( + query + ); + + const chunks = []; + for await (const chunk of stream) { + chunks.push(chunk); + } + + return chunks.join(""); +} + + +async function main(port) { + const hostname = '127.0.0.1'; + + const server = http.createServer((req, res) => { + res.statusCode = 200; + + // Create URL object and parse query parameters + const urlObj = new URL(req.url, `http://${req.headers.host}`); + const queryParams = urlObj.searchParams; + + // Get query parameters with default values if not provided + const q = queryParams.get('q') || "Create an error 500 message explaining that the user didn't input a query and optionally a URL."; + const www = queryParams.get('www') || "docChatterThing.testfile.invalid"; + + // Get reply and send response + getReply(q, www).then(answer => { + res.setHeader('Content-Type', 'text/plain'); + res.end(String(answer)); + }).catch(err => { + res.statusCode = 500; + res.end(`Internal Server Error: ${err.message}`); + }); + }); + + server.listen(port, hostname, () => { + console.log(`Server running at http://${hostname}:${port}/`); + }); +} + +main(8543) \ No newline at end of file diff --git a/package.json b/package.json index a5a9066..f5de0e4 100644 --- a/package.json +++ b/package.json @@ -1,16 +1,25 @@ -{ - "name": "sneedgroup-agent", - "version": "1.0.0", - "description": "", - "main": "index.mjs", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "Samuel Lord", - "license": "SEE LICENSE IN LICENSE", - "dependencies": { - "ollama": "^0.5.0", - "ollama-js-client": "^1.0.1", - "readline": "^1.3.0" - } -} +{ + "dependencies": { + "@langchain/community": "^0.2.28", + "@langchain/ollama": "^0.0.4", + "cheerio": "^1.0.0", + "puppeteer": "^23.1.1" + }, + "name": "sneed-agent", + "version": "1.0.0", + "description": "Sneed Agent", + "main": "index.mjs", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/sneed-group/sneed-agent.git" + }, + "author": "Sneed Group", + "license": "SEE LICENSE IN LICENSE", + "bugs": { + "url": "https://github.com/sneed-group/sneed-agent/issues" + }, + "homepage": "https://github.com/sneed-group/sneed-agent#readme" +}