// The real Repl on the real Conversation and Store, with a scripted host in // place of the model loop (no model is called). Used by tests/repl_persist.py, // which starts it repeatedly under chosen shells and checks the vault. // // repl_probe [--profile NAME] [--continue] [--yolo] [--oneshot TEXT] // // Host behaviour: every input line becomes a user message plus the assistant // reply "echo: "; the input "CRASH" saves a checkpoint with the turn // still open and kills the process (an interrupted turn for --continue). #include #include #include #include #include "config/config.h" #include #include "repl/boot.h" #include "repl/interrupt.h" #include "repl/repl.h" #include "session/conversation.h" #include "session/shell_context.h" #include "store/store.h" using namespace detz; class EchoHost : public repl::ReplHost { public: explicit EchoHost(session::Conversation& conv) : conv_(conv) {} std::string run_turn(const std::string& text) override { conv_.begin_turn(text); conv_.add_message("user", text); if (text == "CRASH") { conv_.checkpoint(); std::fflush(stdout); ::_exit(9); } if (text == "SLEEP") { // a long turn that honours Ctrl-C like the model loop must conv_.checkpoint(); for (int i = 0; i < 100; i++) { if (repl::Interrupt::requested()) throw repl::TurnInterrupted(); ::usleep(50000); } } std::string reply = "echo: " + text; conv_.add_message("assistant", reply); conv_.close_turn(); return reply; } private: session::Conversation& conv_; }; int main(int argc, char** argv) { std::string profile = "default", oneshot; bool resume = false, yolo = false, has_oneshot = false; for (int i = 1; i < argc; i++) { std::string a = argv[i]; if (a == "--profile" && i + 1 < argc) profile = argv[++i]; else if (a == "--continue") resume = true; else if (a == "--yolo") yolo = true; else if (a == "--throw") { // uncaught exception with the debug log on: the terminate hook must log it repl::Boot::configure_debug(std::string("file"), std::nullopt); throw std::runtime_error("kaboom"); } else if (a == "--oneshot" && i + 1 < argc) { oneshot = argv[++i]; has_oneshot = true; } } repl::BootOptions boot; boot.profile = profile; boot.yolo = yolo; boot.version = "probe"; boot.mode = has_oneshot ? "one-shot" : "repl"; auto session = repl::Boot::open(boot); session::Conversation& conv = *session->conversation; EchoHost host(conv); repl::Repl::Options options; options.version = "probe"; options.resume = resume; repl::Repl app(conv, host, options); if (has_oneshot) return app.oneshot(oneshot); return app.run(); }