Warning: session_start(): open(/var/lib/php/sessions/sess_645to7rjqqvtn3unhttcpp1078, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
!7
concept StandardScript {
S scriptID;
}
cmodule Cruddie > DynPrintLogAndEnabled {
!include #1027628 // HTTP+HTTPS servers
transient S salt;
transient WebChatBot chatBot;
transient CRUD standardScriptsCRUD;
transient CRUD conversationsCRUD;
switchable int vadUpdateInterval = 100;
switchable double listenTime = 3.0; // listen for 3 seconds after voice activity
switchable double listenTimeAfterActualSpeech = 10.0; // listen for 10 seconds after actual speech recognized
switchable double transcriptTitleShowTime = 5.0; // how long to show recognized text in window title
S myLink() { ret "https://cruddie.site/"; }
S botLink() { ret "bot"; /*ret appendWithSlash(myLink(), "bot");*/ }
switchable S frontendModuleLibID = "#1027675/ChatBotFrontend";
switchable S backendModuleLibID = "#1027591/DynamicClassesMultiCRUD";
transient S cmdsSnippetID = #1027616;
start {
standardScriptsCRUD = new CRUD(StandardScript);
conversationsCRUD = new CRUD(Conversation);
thread enter { pcall {
File saltFile = secretProgramFile("salt.txt");
S salt = trimLoadTextFile(saltFile);
if (empty(salt)) {
saveTextFile(saltFile, salt = randomID());
print("Made salt");
}
dm_restartOnFieldChange enabled();
if (!enabled) ret;
chatBot = new WebChatBot;
chatBot.preprocess = s -> {
S s2 = googleDecensor(s);
print("Preprocessing: " + s + " => " + s2);
ret s2;
};
chatBot.templateID = #1027690;
chatBot.baseLink = botLink();
chatBot.thoughtBot = new ThoughtBot;
chatBot.jsOnMsgHTML = "window.processNewStuff(src);";
chatBot.onBotShown = [[ {
var input = $("#status_message")[0];
console.log("input: " + input);
if (input)
new Awesomplete(input, {
minChars: 1,
list: [
"I call you Fido",
"What is your name?",
'add script "#1027704/SomeCruddieScripts/RepeatAfterMe"',
'add script "#1027704/SomeCruddieScripts/GoPublic"',
'clear scripts'
]
});
} ]];
chatBot.afterHeading = "` + ('webkitSpeechRecognition' in window ? ` " + tag("button", "...", onclick := lineBreaksToSpaces([[
startOrStop();
if (bigOn) { lastHadVoice = Date.now(); startVAD(); startUpdater(); humOn(); }
else stopVAD();
]]), type := 'button, class := 'speechOnBtn, disabled := 'disabled, display := 'inline)
/*+ hjs([[console.log("Updating"); window.srUpdate();]])*/ + "` : ``) + `"
+ hdiv(hsnippetimg(#1102908, width := 24, height := 24, title := "Someone is speaking (either me or you)"), style := "display: inline; visibility: hidden; margin-left: 10px", class := "vadStatus")
+ hdiv(hsnippetimg(#1102909, width := 24, height := 24, title := "Listening"), style := "display: inline; visibility: hidden; margin-left: 10px", class := "listenStatus")
+ hdiv(small("Note: All conversations are public rn " + targetBlank("https://www.youtube.com/watch?v=StxQerL0D-o", "(why)")));
chatBot.moreStuff = "window.srUpdate();";
chatBot.start();
set redirectHttpToHttps;
start_webServers(serverSocketFactory_botCompanyEtc());
}}
}
O webServe(S uri, SS params) {
Pair spamCheck = spamBlocker.checkRequest(uri, serveHttp_clientIP());
if (spamCheck.b) {
sleepSeconds(60.0);
ret print("go away");
}
printVars("webServe", +uri);
//S cookie = serveHttp_cookieHandling();
if (startsWith(uri, "/.well-known/"))
ret loadTextFile(userDir("validation.txt"));
// new-style cookie isn't really used yet
S newStyleCookie = nu ServeHttp_CookieHandler(verbose := true).handle();
new Matches m;
S uri2 = appendSlash(uri);
if (startsWith(uri2, "/bot/", m))
ret chatBot.html("/" + m.rest(), params);
if (eq(uri, "/awesomplete.css")) ret serveWithContentType(loadSnippet(#2000595), "text/css");
if (eq(uri, "/awesomplete.js")) ret serveText(loadSnippet(#2000594));
if (endsWith(uri, ".map")) ret "";
if (eq(uri, "/frames"))
ret serveFrameSet(params);
S jsOnSpeech = [[
if (transcript == 'stop listening')
stopVAD();
else
window.submitAMsg(transcript);
lastHeard = transcript;
lastHeardWhen = Date.now();
]];
S sayBotMsgsScript = [[
window.processNewStuff = function(src) {
]] + (eq(params.get('quiet), "1") ? "" : [[
if ($("#speechResults") == null) return; // no speech
// we assume that webkit speech synthesis is present
// when there is webkit speech recognition
if (!bigOn) return; // not enabled
console.log("Got speech");
var match = src.match(/\d+/);
if (match == null) return;
if (src.match(/NEW DIALOG -->/)) return;
console.log("Got incremental");
var re = /bot-utterance">(.*?)]] // took out async
)
+ hbody(hOnBottom(
p(hsnippetimage(#1102905))
+ p("Chat bot is doing basic stuff. Documentation coming up.")
+ stats()
+ hSpeechRecognition(jsOnSpeech, true, "en-US", false,
noWebKit := p("Use Chrome if you want speech recognition"),
+speechUI)
+ hjavascript([[
function say(text) {
console.log("Saying: " + text);
var u = new SpeechSynthesisUtterance(text);
u.lang = 'en-US';
u.onstart = function() { console.log("speech start"); meSpeaking = true; };
u.onend = function() { meSpeaking = false; };
window.speechSynthesis.speak(u);
}
]] + sayBotMsgsScript)
+ hjs((S) chatBot.html("/", litmap(), returnJS := true))
+ hVAD(
[[console.log("voice start"); $(".vadStatus").css("visibility", "visible");]],
[[console.log("voice stop"); $(".vadStatus").css("visibility", "hidden");]],
false)
+ hjs_setTitleStatus()
+ hjs(replaceDollarVars([[
var updater;
var lastHadVoice = 0;
var lastHeard, lastHeardWhen = 0;
var meSpeaking = false;
//audioMeterDebug = true;
function startUpdater() {
if (updater) return;
console.log("Starting updater");
updater = setInterval(vadMagicUpdate, $interval);
srPause = true;
}
function stopUpdater() {
if (!updater) return;
console.log("Stopping updater");
clearInterval(updater);
updater = null;
window.resetTitle();
}
function vadMagicUpdate() {
if (!bigOn) { stopUpdater(); return; }
var now = Date.now();
var hasVoice = vadHasVoice();
var clipping = vadHasClipping();
if (hasVoice) lastHadVoice = now;
var shouldListen = !meSpeaking && (lastHadVoice >= now-$listenTime || lastHeardWhen >= now-$listenTimeAfterActualSpeech);
var titleStatus = "";
if (lastHeardWhen >= now-$transcriptTitleShowTime)
titleStatus = lastHeard + " |";
else if (shouldListen)
titleStatus = $listeningSymbol;
else if (bigOn)
titleStatus = $ear;
if (clipping)
titleStatus = "! " + titleStatus;
window.setTitleStatus(titleStatus);
if (srPause != !shouldListen) {
console.log(shouldListen ? "Listening" : "Not listening");
srPause = !shouldListen;
srUpdate();
if (shouldListen) humOn(); else humOff();
}
}
// debug mic level
/*setInterval(function() {
if (audioMeter)
console.log("Mic level: " + audioMeter.absLevel);
}, 1000);*/
]],
interval := vadUpdateInterval,
listenTime := toMS(listenTime),
listenTimeAfterActualSpeech := toMS(listenTimeAfterActualSpeech),
transcriptTitleShowTime := toMS(transcriptTitleShowTime),
listeningSymbol := jsQuote(/*"[LISTENING]"*/unicode_cloud()),
ear := jsQuote(unicode_ear())))
)/*, onLoad := "startAwesomplete()"*/));
}
S cookieToCaseID(S cookie) {
ret md5(cookie + salt);
}
class Request {
S cookie, caseID;
S frontend, backend; // module IDs
*(S *cookie) {
caseID = cookieToCaseID(cookie);
frontend = dm_makeModuleWithParams_systemQ(frontendModuleLibID, +caseID);
backend = dm_makeModuleWithParams_systemQ(backendModuleLibID, +caseID);
dm_call(frontend, 'connectToBackend, backend);
dm_call(frontend, 'importCmdsFromSnippetIfEmpty, cmdsSnippetID);
dm_call(frontend, 'addScripts, collect scriptID(list StandardScript()));
Conversation conv = uniq Conversation(+cookie);
forwardSwappableFunctionToObject(dm_mod(frontend),
'chatLog_userMessagesOnly, func -> LS {
map(m -> m.text, filter(conv.allMsgs(), m -> m.fromUser))
}, 'get);
printVars(+caseID, +backend);
}
}
class ThoughtBot {
new ThreadLocal request;
void setSession(S cookie, SS params) {
//session.set(uniq_sync(Session, +cookie));
request.set(new Request(cookie));
}
S initialMessage() {
//ret "Hello from module " + request->backend;
ret (S) dm_call(request->backend, 'answer, "stats");
}
S answer(S s) {
ret (S) dm_call(request->frontend, 'answer, s);
}
}
S stats() {
ret p(joinWithBR(
"Server temperature is " + dm_cpuTemperature(),
n2(numberOfCruddies(), "cruddie") + ", " + n2(vmBus_countResponses chatBotFrontend()) + " loaded",
));
}
int numberOfCruddies() {
ret countDirsInDir(getProgramDir(beforeSlash(frontendModuleLibID)));
}
visual
jtabs("Main", super,
"Standard Scripts", standardScriptsCRUD.visualize(),
"Conversations", conversationsCRUD.visualize());
S serveFrameSet(SS params) {
ret hhtml(hhead_title("CRUDDIE with frames") +
tag frameset(
tag frame("", name := "leftmonitor") +
tag frame("", src := appendParamsToURL(myLink(), params)) +
tag frame("", name := "rightmonitor"), cols := "*,550,*"));
}
}