Auto-generate temp file with -n flag
- Added UUID v4 generation using <random> and <filesystem> headers - When -n is specified without -F, create a temp file in system temp dir - Temp file is named harness-<uuid>.json - Print temp file path to stderr when session exits - Updated help message to reflect new behavior - Added test_auto_temp_file.sh to verify: - Temp file creation with -n alone - Path printed to stderr - Existing -F <file> -n behavior preserved - UUID uniqueness
This commit is contained in:
+60
-2
@@ -18,9 +18,12 @@
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <filesystem>
|
||||
#include <random>
|
||||
#include <iomanip>
|
||||
|
||||
static const std::vector<AgentProfile> profiles = {
|
||||
#if !defined(_WIN32)
|
||||
@@ -39,6 +42,36 @@ static const std::vector<std::string> default_tools =
|
||||
{
|
||||
};
|
||||
|
||||
// UUID v4 generation using <random> and <filesystem> only
|
||||
static std::string generate_uuid() {
|
||||
std::random_device rd;
|
||||
std::mt19937 gen(rd());
|
||||
std::uniform_int_distribution<> dis(0, 15);
|
||||
std::uniform_int_distribution<> dis2(8, 11); // for variant bits
|
||||
|
||||
std::ostringstream ss;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
ss << std::hex << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 4; i++) {
|
||||
ss << std::hex << dis(gen);
|
||||
}
|
||||
ss << "-4"; // version 4
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ss << std::hex << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
ss << std::hex << dis2(gen);
|
||||
for (int i = 0; i < 3; i++) {
|
||||
ss << std::hex << dis(gen);
|
||||
}
|
||||
ss << "-";
|
||||
for (int i = 0; i < 12; i++) {
|
||||
ss << std::hex << dis(gen);
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
OllamaConfig cfg;
|
||||
@@ -79,6 +112,7 @@ int main(int argc, char** argv) {
|
||||
};
|
||||
|
||||
char const* file_to_open = nullptr;
|
||||
std::string auto_temp_file; // Path to auto-generated temp file (if any)
|
||||
char const* prompt = nullptr;
|
||||
bool start_new = false;
|
||||
bool list_models = false;
|
||||
@@ -168,11 +202,11 @@ int main(int argc, char** argv) {
|
||||
{
|
||||
std::cout << "Usage: drharness [options]\n"
|
||||
<< "Options:\n"
|
||||
<< " -F <file> Chat file (required)\n"
|
||||
<< " -F <file> Chat file\n"
|
||||
<< " -p <file> Pretty print a saved conversation JSON file\n"
|
||||
<< " -t <tool> Tool name (can be specified multiple times)\n"
|
||||
<< " -s <name> Skill name to enable (can be specified multiple times)\n"
|
||||
<< " -n Start a new conversation\n"
|
||||
<< " -n Start a new conversation (auto-generates temp file if -F not specified)\n"
|
||||
<< " -m <prompt> Prompt message (required)\n"
|
||||
<< " -M <model> Ollama model name\n"
|
||||
<< " -f Open editor with full history (requires -F)\n"
|
||||
@@ -280,6 +314,25 @@ int main(int argc, char** argv) {
|
||||
else
|
||||
agent_tools = master_registery.create_subregistry(tools);
|
||||
|
||||
// Auto-generate temp file if -n is specified without -F
|
||||
if (start_new && !file_to_open) {
|
||||
std::filesystem::path temp_dir = std::filesystem::temp_directory_path();
|
||||
std::string uuid = generate_uuid();
|
||||
auto temp_file_path = temp_dir / ("harness-" + uuid + ".json");
|
||||
|
||||
// Create empty temp file
|
||||
std::ofstream temp_file(temp_file_path);
|
||||
temp_file.close();
|
||||
|
||||
if (!std::filesystem::exists(temp_file_path)) {
|
||||
std::cerr << "Error: Failed to create temp file" << std::endl;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
file_to_open = temp_file_path.string().c_str();
|
||||
auto_temp_file = temp_file_path.string();
|
||||
}
|
||||
|
||||
if (!file_to_open)
|
||||
{
|
||||
std::cerr << "Chat file is required (-F)" << std::endl;
|
||||
@@ -333,4 +386,9 @@ int main(int argc, char** argv) {
|
||||
std::ofstream harness_state(file_to_open);
|
||||
std::cout << reply << std::endl;
|
||||
harness_state << nlohmann::json(harness.serialize());
|
||||
|
||||
// Print the auto-generated temp file path to stderr if it was auto-created
|
||||
if (!auto_temp_file.empty()) {
|
||||
std::cerr << auto_temp_file << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,3 +37,4 @@ add_dr_test(test_editor)
|
||||
add_dr_test(test_tool_skill)
|
||||
add_dr_test(test_skill_filter)
|
||||
add_dr_test(test_skill_override)
|
||||
add_dr_test(test_auto_temp_file)
|
||||
|
||||
Executable
+62
@@ -0,0 +1,62 @@
|
||||
#!/bin/bash
|
||||
# test_auto_temp_file.sh - Validates auto-generation of temp files with -n flag
|
||||
|
||||
# Test 1: -n alone creates a temp file and prints path to stderr
|
||||
OUTPUT=$("${DRHARNESS}" -n -m "test" -d <<< "$(be_done 'Test response from mock')" 2> stderr_output)
|
||||
|
||||
# Check that we got the expected response
|
||||
if [ "${OUTPUT}" != "Test response from mock" ]; then
|
||||
echo "FAIL: Expected 'Test response from mock', got '${OUTPUT}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check that stderr contains a path matching harness-*.json pattern
|
||||
if ! grep -qE 'harness-[0-9a-f-]+\.json' stderr_output; then
|
||||
echo "FAIL: Expected temp file path in stderr, got: $(cat stderr_output)"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract the temp file path from stderr (last line)
|
||||
TEMP_FILE=$(grep -E 'harness-[0-9a-f-]+\.json' stderr_output | tail -1)
|
||||
|
||||
# Verify the temp file exists
|
||||
if [ ! -f "${TEMP_FILE}" ]; then
|
||||
echo "FAIL: Temp file '${TEMP_FILE}' does not exist"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify the temp file has content (the harness state was written to it)
|
||||
FILE_SIZE=$(wc -c < "${TEMP_FILE}")
|
||||
if [ "${FILE_SIZE}" -eq 0 ]; then
|
||||
echo "FAIL: Temp file is empty, expected harness state to be written"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASS: auto_temp_file - temp file created and path printed to stderr"
|
||||
|
||||
# Test 2: -F <file> -n still works as before (preserves existing behavior)
|
||||
touch "${TEST_TEMP_DIR}/existing.json"
|
||||
EXISTING_OUTPUT=$("${DRHARNESS}" -F existing.json -n -m "test" -d <<< "$(be_done 'Existing file test')" 2> existing_stderr_output)
|
||||
|
||||
if [ "${EXISTING_OUTPUT}" != "Existing file test" ]; then
|
||||
echo "FAIL: Expected 'Existing file test', got '${EXISTING_OUTPUT}'"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# The existing file should not have been modified if it was empty initially
|
||||
# (except for the harness state being written to it)
|
||||
|
||||
# Test 3: Verify two -n calls create different files
|
||||
FIRST_OUTPUT=$("${DRHARNESS}" -n -m "test" -d <<< "$(be_done 'First')" 2> first_stderr)
|
||||
SECOND_OUTPUT=$("${DRHARNESS}" -n -m "test" -d <<< "$(be_done 'Second')" 2> second_stderr)
|
||||
|
||||
FIRST_FILE=$(grep -E 'harness-[0-9a-f-]+\.json' first_stderr | tail -1)
|
||||
SECOND_FILE=$(grep -E 'harness-[0-9a-f-]+\.json' second_stderr | tail -1)
|
||||
|
||||
if [ "${FIRST_FILE}" = "${SECOND_FILE}" ]; then
|
||||
echo "FAIL: Two -n calls created the same file: ${FIRST_FILE}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "PASS: auto_temp_file - UUID uniqueness verified"
|
||||
echo "PASS: auto_temp_file -F behavior preserved"
|
||||
Reference in New Issue
Block a user