Warning: session_start(): open(/var/lib/php/sessions/sess_bmap6plcf5ouis39jk629aonmh, 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
set flag DynModule. // for transpilation
set flag dm_evalJava_withModule_debug.
set flag veryQuickJava3_debug.
cmodule2 GazelleMultiBot > DynGazelleBot {
switchable int maxEvalResultLength = oneMegabyte_int();
switchable double evalTimeout = 30.0;
switchable long botProcessed; // timestamp of last post processed by bots
switchable int maxBotAnswerLength = 100000;
transient new L bots;
Map allPosts = syncTreeMap();
transient Map loadedCodePosts = syncTreeMap();
transient new O couldntLoadCode;
transient Lock codeLoadLock = lock();
set flag NoNanoHTTPD.
!include #1029545 // API for Eleu
class Bot {
S name;
*() {}
*(S *name) {}
*(S *name, IVF1 *handlePost) {}
swappable void handlePost(GazellePost post) {}
GazelleBotCred cred() { ret GazelleBotCred(_user, _botToken, name); }
void postReply(GazellePost post, S text, S type, S title default null) {
gazelle_createPost(cred(), text, type, refs := post.id, +title);
}
}
srecord CreatePost(L params) {}
start {
dm_useLocalMechListCopies();
grabLoop.handlePosts = posts -> {
dm_mediumRefreshTranspiler();
grabLoop.handlePosts_base(posts);
for (GazellePost post : posts)
setField(botProcessed := max(botProcessed, post.modified));
};
// legacy conversion to sort allPosts
setField_noCheck(allPosts := asSyncTreeMap(allPosts));
bots.add(new Bot("Math Bot", post -> {
if (post.creating) ret;
gazelle_mathBot1_handlePost_2(_user, _botToken, post);
}));
bots.add(new Bot("Code Safety Checker") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "JavaX Code"))
gazelle_createPost(cred(), codeSafetyCheckResult(post.text), "Code Safety", refs := post.id);
}
});
bots.add(new Bot("Safe Code Runner") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "JavaX Code")) {
S code = post.text;
if (isCodeSafe(code)) {
code = prepareCode(code, post);
//S out = shorten(maxEvalResultLength, runCode(code));
S text, type = "Code Result", title = "";
try {
O result = evalCode(code, post);
if (result cast CreatePost) {
O[] params = toObjectArray(result.params);
text = (S) optPar text(params);
type = (S) optPar type(params, type);
title = (S) optPar title(params);
} else
text = str_shortenSynthetic(result);
} catch print e {
text = getStackTrace(e);
}
gazelle_createPost(cred(), text, type, +title, refs := post.id);
}
}
}
});
bots.add(new Bot("Run Code On All Posts") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "Instruction") && match("Please run this code on all posts", post.text)) {
long ref = gazelle_firstPostRef(post.id);
if (ref == 0) ret;
S code = gazelle_text(ref);
if (!isCodeSafe(code)) ret;
S code2 = "ret func(S post) { " + code + " };";
O function = evalCode(code2);
new LS lines;
S out = shorten(maxEvalResultLength, runCode(code));
for (GazellePost post2 : cloneValues(allPosts)) {
lines.add("Post " + post2.id + " (" + quote(shorten(20, post2.text)) + "): " + shorten(80, runFunc(() -> callF(function, post2.text))));
}
gazelle_createPost(cred(), lines(lines), "Code Result", refs := post.id);
}
}
});
bots.add(new Bot("Mark identifiers safe") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (/*eqic(post.type, "Instruction")
&&*/ post.creator.isMaster
&& match("Mark safe", post.text)) {
S text = getPost(first(post.postRefs)).text;
LS ids = tok_identifiersInOrder(regexpFirstGroupIC("Unknown identifiers: (.+)", text));
print("Marking safe: " + ids);
postReply(post, markSafe(ids), "Marked safe");
}
}
});
bots.add(new Bot("Post Deleter") {
void handlePost(GazellePost post) {
if (post.creating) ret;
if (eqic(post.type, "Instruction")
&& post.creator.isMaster
&& match("Delete mentioned posts", post.text)) {
long ref = gazelle_firstPostRef(post.id);
if (ref == 0) ret;
S text = gazelle_text(ref);
L postIDs = allToLong(regexpAllFirstGroups(gazelle_postMentionRegexp(), text));
print("Deleting posts: " + postIDs);
if (nempty(postIDs)) {
Map result = gazelle_deletePosts(cred(), postIDs);
postReply(post, str(result), "Deletion result");
} else
postReply(post, "No mentioned posts found", "Deletion result");
}
}
});
bots.add(new Bot("Detector Runner") {
void handlePost(GazellePost post) {
if (post.creating) ret;
ret unless eqic(post.type, "Instruction")
&& match("Please run detector", post.text);
try {
long detectorID = post.refWithTagOrFail("detector");
long posExamplesID = post.refWithTagOrFail("positive examples");
long negExamplesID = post.refWithTagOrFail("negative examples");
S code = getPost(detectorID).text;
LS posExamples = tlft(getPost(posExamplesID).text);
LS negExamples = tlft(getPost(negExamplesID).text);
LPair examples = trueFalseBPairs(posExamples, negExamples);
if (!isCodeSafe(code)) fail("Detector code not safe");
IF1 detector = proxy IF1(evalCode(code));
new LS good;
new LS bad;
new Scorer scorer;
long time = sysNow();
evalWithTimeoutOrFail(evalTimeout, r {
for (Pair example : examples) {
S result = runFunc(() -> detector.get(example.a));
bool ok = eq(result, str(example.b));
scorer.add(ok);
S line = (ok ? "OK" : example.b ? "False negative" : "False positive")
+ " (" + shorten(10, result) + "): " + example.a;
(ok ? good : bad).add(line);
}
});
time = sysNow()-time;
S text = "Detector code:\n\n" + indentx(code) + "\n\n"
+ n2(good, "correct answer") + ", " + n2(bad, "bad answer") + ". Runtime: " + n2(time) + " ms\n\n"
+ or2(trim(lines(concatLists(bad, ll(""), good))), "No errors");
S title = "Score for detector " + detectorID + ": " + scorer;
gazelle_createPost(cred(), text, "Detector Score", +title,
refs := joinWithSpace(ll(post.id, detectorID, posExamplesID, negExamplesID)),
refTags := linesLL_rtrim("", "detector", "positive examples", "negative examples"));
} catch e {
postReply(post, getStackTrace(e), "Error");
}
}
});
}
void handlePost(GazellePost post) {
allPosts.put(post.id, post);
change();
loadedCodePosts.remove(post.id);
if (post.modified > botProcessed) {
print("modified: " + post.modified + "/" + botProcessed);
for (Bot bot : bots) pcall {
bot.handlePost(post);
}
}
}
// if post != null, store transpilation
O evalCode(S code, GazellePost post default null) {
printWithIndent("CODE> ", code);
veryQuickJava_transpiled.set(post != null ? "" : null); // request transpilation
try {
ret dm_javaEvalWithTimeout(evalTimeout, code);
} finally {
if (post != null) {
S java = veryQuickJava_transpiled!;
print("Transpilation for " + post.id + ": " + shorten(java));
saveTextFile(transpilationFile(post.id), nullOnEmpty(java));
}
}
}
// assumes code is safety-checked
S runCode(S code) {
printWithIndent("CODE> ", code);
ret runFunc(() -> str_shortenSynthetic(dm_javaEval(code)));
}
// run IF0 with timeout, exception to string, convert result to string
S runFunc(IF0 f) {
ret str_shortenSynthetic(evalWithTimeoutOrException(evalTimeout, func {
try {
ret str_shortenSynthetic(f!);
} catch e {
ret getStackTrace(e);
}
}));
}
L repliesTo(GazellePost post) {
ret filter(values(allPosts), p -> contains(p.postRefs, post.id));
}
L repliesWithTag(GazellePost post, S tag) {
Pair pair = pair(post.id, upper(tag));
ret filter(repliesTo(post), p -> contains(mapPairsB toUpper(p.taggedRefs()), pair));
}
GazellePost getPost(long id) {
ret allPosts.get(id);
}
S getPostText(long id) {
ret getPost(id).text;
}
Cl getAllPosts() {
ret values(allPosts);
}
CreatePost createPost(O... _) {
ret new CreatePost(asList(_));
}
CodeSafetyChecker codeSafetyChecker() {
new CodeSafetyChecker checker;
checker.init();
checker.markSafe("getAllPosts");
ret checker;
}
S codeSafetyCheckResult(S code) {
CodeSafetyChecker checker = codeSafetyChecker();
checker.checkCode(code);
ret checker.verbalCheckResult();
}
bool isCodeSafe(S code) {
CodeSafetyChecker checker = codeSafetyChecker();
checker.checkCode(code);
ret checker.isSafe();
}
S prepareCode(S code, GazellePost post) {
code = tok_addReturn(code);
// define implicit vars and functions
// post = text of parent post
if (containsJavaToken(code, "post")) {
long ref = gazelle_firstPostRef(post.id);
if (ref != 0)
code = "S post = " + quote(gazelle_text(ref)) + ";\n" + code;
}
// post = text of grandparent post
if (containsJavaToken(code, "post2")) {
long ref = gazelle_firstPostRef(gazelle_firstPostRef(post.id));
if (ref != 0)
code = "S post2 = " + quote(gazelle_text(ref)) + ";\n" + code;
}
if (containsJavaToken(code, "getAllPosts"))
code = [[
embedded Cl getAllPosts() {
ret (Cl) quickImport(dm_call(dm_current_generic(), "getAllPosts"));
}
]] + code;
if (containsJavaToken(code, "createPost"))
code = [[
embedded O createPost(O... _) {
ret dm_call(dm_current_generic(), "createPost", _);
}
]] + code;
// optimize gazelle_text
if (containsJavaToken(code, "gazelle_text")) {
code = [[
embedded S gazelle_text(long id) {
ret (S) dm_call(dm_current_generic(), "getPostText", id);
}
]] + code;
}
ret code;
}
O html(IWebRequest req) {
new Matches m;
if (startsWith(req.uri(), "/chatBotReply/", m) && isInteger(m.rest())) {
long postID = parseLong(m.rest());
GazellePost post = getPost(postID);
if (post == null) ret serve404("Post " + postID + " not found");
O code = codeForPost(post);
if (code == couldntLoadCode) ret serve500("Couldn't load code for post");
S q = req.params().get("q"); // user input
if (empty(q)) ret "";
ret serveJSON(litorderedmap(answer := shorten(maxBotAnswerLength, evalWithTimeoutOrFail(evalTimeout,
() -> strOrEmpty(callF(code, q))))));
}
if (startsWith(req.uri(), "/transpilation/", m) && isInteger(m.rest())) {
long postID = parseLong(m.rest());
GazellePost post = getPost(postID);
if (post == null) ret serve404("Post " + postID + " not found");
S src = loadTextFile(transpilationFile(post.id));
if (empty(src))
src = "No transpilation found for post " + postID + "." +
(!post.isJavaXCode() ? "Code is not a code post." : "Please try \"Touch post\" and wait a few seconds");
else pcall {
src = javaPrettyPrint(src);
}
ret serveText(src);
}
ret "Bot here";
}
O codeForPost(GazellePost post) {
lock codeLoadLock;
O code = loadedCodePosts.get(post.id);
if (code == null) {
try {
S codeText = post.text;
if (!isCodeSafe(codeText)) fail("Code is not safe");
codeText = prepareCode(codeText, null);
code = evalCode(codeText, post);
} catch print e {
code = couldntLoadCode;
}
loadedCodePosts.put(post.id, code);
}
ret code;
}
File transpilationFile(long postID) {
ret programFile("Post-Transpilations/" + postID + ".java");
}
}