studio: fix data roots and refine datasets

This commit is contained in:
scawful
2025-12-30 11:24:15 -05:00
parent 573ebf8247
commit 2711cf1658
12 changed files with 268 additions and 93 deletions

View File

@@ -2,8 +2,35 @@
#include "logger.h"
#include "filesystem.h"
#include <cstdlib>
#include <fstream>
namespace {
std::filesystem::path ResolveContextRoot() {
const char* env_root = std::getenv("AFS_CONTEXT_ROOT");
if (env_root && env_root[0] != '\0') {
auto path = afs::studio::core::FileSystem::ResolvePath(env_root);
if (afs::studio::core::FileSystem::Exists(path)) {
return path;
}
}
auto preferred = afs::studio::core::FileSystem::ResolvePath("~/src/context");
if (afs::studio::core::FileSystem::Exists(preferred)) {
return preferred;
}
auto fallback = afs::studio::core::FileSystem::ResolvePath("~/.context");
if (afs::studio::core::FileSystem::Exists(fallback)) {
return fallback;
}
return preferred;
}
} // namespace
namespace afs {
namespace studio {
@@ -13,7 +40,7 @@ RegistryReader::RegistryReader(const std::filesystem::path& registry_path)
: registry_path_(registry_path) {}
std::filesystem::path RegistryReader::ResolveDefaultPath() const {
return core::FileSystem::ResolvePath("~/.context/models/registry.json");
return ResolveContextRoot() / "models" / "registry.json";
}
bool RegistryReader::Exists() const {

View File

@@ -36,9 +36,12 @@ std::optional<std::filesystem::path> ResolveHafsScawfulRoot() {
return plugin_path;
}
auto legacy_path = studio::core::FileSystem::ResolvePath("~/src/trunk/scawful/research/afs_scawful");
if (studio::core::FileSystem::Exists(legacy_path)) {
return legacy_path;
auto trunk_root = ResolveTrunkRoot();
if (trunk_root) {
auto candidate = *trunk_root / "scawful" / "research" / "afs_scawful";
if (studio::core::FileSystem::Exists(candidate)) {
return candidate;
}
}
return std::nullopt;
@@ -121,6 +124,57 @@ std::filesystem::path ResolveDatasetRegistryPath() {
return ResolveTrainingRoot() / "index" / "dataset_registry.json";
}
std::filesystem::path ResolveResourceIndexPath(const std::string& data_root,
const DataLoader::PathExists& exists) {
const char* env_path = std::getenv("AFS_RESOURCE_INDEX");
if (env_path && env_path[0] != '\0') {
return studio::core::FileSystem::ResolvePath(env_path);
}
std::vector<std::filesystem::path> candidates;
auto training_root = ResolveTrainingRoot();
if (!training_root.empty()) {
candidates.push_back(training_root / "index" / "resource_index.json");
candidates.push_back(training_root / "resource_index.json");
}
if (!data_root.empty()) {
auto data_path = std::filesystem::path(data_root);
candidates.push_back(data_path / "index" / "resource_index.json");
candidates.push_back(data_path / "resource_index.json");
}
for (const auto& candidate : candidates) {
if (exists(candidate.string())) {
return candidate;
}
}
return {};
}
std::filesystem::path ResolveTrainingDataPath(const std::string& filename,
const std::string& data_root,
const DataLoader::PathExists& exists) {
std::vector<std::filesystem::path> candidates;
if (!data_root.empty()) {
auto data_path = std::filesystem::path(data_root);
candidates.push_back(data_path / filename);
candidates.push_back(data_path / "index" / filename);
}
auto training_root = ResolveTrainingRoot();
if (!training_root.empty()) {
candidates.push_back(training_root / filename);
candidates.push_back(training_root / "index" / filename);
}
for (const auto& candidate : candidates) {
if (exists(candidate.string())) {
return candidate;
}
}
return {};
}
constexpr float kTrendDeltaThreshold = 0.05f;
bool IsWhitespaceOnly(const std::string& s) {
@@ -168,14 +222,20 @@ bool DataLoader::Refresh() {
last_error_.clear();
last_status_ = LoadStatus{};
if (!path_exists_(data_path_)) {
const bool base_exists = !data_path_.empty() && path_exists_(data_path_);
const auto training_root = ResolveTrainingRoot();
const bool training_exists = !training_root.empty() && path_exists_(training_root.string());
if (!base_exists && !training_exists) {
last_error_ = "Data path does not exist: " + data_path_;
LOG_ERROR(last_error_);
last_status_.error_count = 1;
last_status_.last_error = last_error_;
last_status_.last_error_source = "data_path";
} else {
LOG_INFO("DataLoader: Refreshing from " + data_path_);
const auto& root = base_exists ? data_path_ : training_root.string();
if (!root.empty()) {
LOG_INFO("DataLoader: Refreshing from " + root);
}
}
auto next_quality_trends = quality_trends_;
@@ -338,17 +398,16 @@ DataLoader::LoadResult DataLoader::LoadQualityFeedback(
RejectionSummary* rejection_summary) {
LoadResult result;
std::string path = data_path_ + "/quality_feedback.json";
if (!path_exists_(path)) {
LOG_WARN("quality_feedback.json not found at " + path);
return result;
auto path = ResolveTrainingDataPath("quality_feedback.json", data_path_, path_exists_);
if (path.empty()) {
return result;
}
LOG_INFO("DataLoader: Loading " + path);
LOG_INFO("DataLoader: Loading " + path.string());
result.found = true;
std::string content;
std::string read_error;
if (!file_reader_(path, &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
if (!file_reader_(path.string(), &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
result.ok = false;
result.error = read_error.empty() ? "quality_feedback.json is empty" : read_error;
return result;
@@ -456,14 +515,14 @@ DataLoader::LoadResult DataLoader::LoadActiveLearning(
CoverageData* coverage) {
LoadResult result;
std::string path = data_path_ + "/active_learning.json";
if (!path_exists_(path)) return result;
auto path = ResolveTrainingDataPath("active_learning.json", data_path_, path_exists_);
if (path.empty()) return result;
LOG_INFO("DataLoader: Loading " + path);
LOG_INFO("DataLoader: Loading " + path.string());
result.found = true;
std::string content;
std::string read_error;
if (!file_reader_(path, &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
if (!file_reader_(path.string(), &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
result.ok = false;
result.error = read_error.empty() ? "active_learning.json is empty" : read_error;
return result;
@@ -508,14 +567,14 @@ DataLoader::LoadResult DataLoader::LoadTrainingFeedback(
OptimizationData* optimization_data) {
LoadResult result;
std::string path = data_path_ + "/training_feedback.json";
if (!path_exists_(path)) return result;
auto path = ResolveTrainingDataPath("training_feedback.json", data_path_, path_exists_);
if (path.empty()) return result;
LOG_INFO("DataLoader: Loading " + path);
LOG_INFO("DataLoader: Loading " + path.string());
result.found = true;
std::string content;
std::string read_error;
if (!file_reader_(path, &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
if (!file_reader_(path.string(), &content, &read_error) || content.empty() || IsWhitespaceOnly(content)) {
result.ok = false;
result.error = read_error.empty() ? "training_feedback.json is empty" : read_error;
return result;
@@ -574,17 +633,16 @@ DataLoader::LoadResult DataLoader::LoadTrainingFeedback(
DataLoader::LoadResult DataLoader::LoadCuratedHacks(
std::vector<CuratedHackEntry>* curated_hacks) {
LoadResult result;
std::string path = data_path_ + "/curated_hacks.json";
if (!path_exists_(path)) {
LOG_WARN("curated_hacks.json not found at " + path);
auto path = ResolveTrainingDataPath("curated_hacks.json", data_path_, path_exists_);
if (path.empty()) {
return result;
}
LOG_INFO("DataLoader: Loading " + path);
LOG_INFO("DataLoader: Loading " + path.string());
result.found = true;
std::string content;
std::string read_error;
if (!file_reader_(path, &content, &read_error) || content.empty() ||
if (!file_reader_(path.string(), &content, &read_error) || content.empty() ||
IsWhitespaceOnly(content)) {
result.ok = false;
result.error =
@@ -644,17 +702,16 @@ DataLoader::LoadResult DataLoader::LoadCuratedHacks(
DataLoader::LoadResult DataLoader::LoadResourceIndex(ResourceIndexData* resource_index) {
LoadResult result;
std::string path = data_path_ + "/resource_index.json";
if (!path_exists_(path)) {
LOG_WARN("resource_index.json not found at " + path);
auto path = ResolveResourceIndexPath(data_path_, path_exists_);
if (path.empty()) {
return result;
}
LOG_INFO("DataLoader: Loading " + path);
LOG_INFO("DataLoader: Loading " + path.string());
result.found = true;
std::string content;
std::string read_error;
if (!file_reader_(path, &content, &read_error) || content.empty() ||
if (!file_reader_(path.string(), &content, &read_error) || content.empty() ||
IsWhitespaceOnly(content)) {
result.ok = false;
result.error = read_error.empty() ? "resource_index.json is empty" : read_error;
@@ -843,9 +900,17 @@ DataLoader::LoadResult DataLoader::LoadContextGraph(ContextGraphData* context_gr
void DataLoader::MountDrive(const std::string& name) {
auto scawful_root = ResolveHafsScawfulRoot();
std::filesystem::path script_path = scawful_root
? *scawful_root / "scripts" / "mount_windows.sh"
: studio::core::FileSystem::ResolvePath("~/src/trunk/scawful/research/afs_scawful/scripts/mount_windows.sh");
std::filesystem::path script_path;
if (scawful_root) {
script_path = *scawful_root / "scripts" / "mount_windows.sh";
} else {
auto trunk_root = ResolveTrunkRoot();
if (trunk_root) {
script_path = *trunk_root / "scawful" / "research" / "afs_scawful" / "scripts" / "mount_windows.sh";
} else {
script_path = studio::core::FileSystem::ResolvePath("~/src/trunk/scawful/research/afs_scawful/scripts/mount_windows.sh");
}
}
if (studio::core::FileSystem::Exists(script_path)) {
LOG_INFO("DataLoader: Triggering mount using " + script_path.string());

View File

@@ -12,6 +12,7 @@
/// Ctrl+Q - Quit
/// Ctrl+/ - Shortcut editor
#include <cstdlib>
#include <iostream>
#include <string>
@@ -27,8 +28,13 @@ int main(int argc, char* argv[]) {
if (argc > 1) {
data_path_str = argv[1];
} else {
auto preferred = FileSystem::ResolvePath("~/src/training");
data_path_str = FileSystem::Exists(preferred) ? preferred.string() : "~/.context/training";
const char* env_root = std::getenv("AFS_TRAINING_ROOT");
if (env_root && env_root[0] != '\0') {
data_path_str = env_root;
} else {
auto preferred = FileSystem::ResolvePath("~/src/training");
data_path_str = FileSystem::Exists(preferred) ? preferred.string() : "~/.context/training";
}
}
std::filesystem::path data_path = FileSystem::ResolvePath(data_path_str);

View File

@@ -151,6 +151,7 @@ struct AppState {
std::vector<std::string> compared_run_ids;
int selected_generator_index = -1;
std::string selected_generator_name;
int selected_dataset_index = -1;
PlotKind focus_plot = PlotKind::None;
std::map<std::string, bool> domain_visibility;
Workspace current_workspace = Workspace::Dashboard;
@@ -206,6 +207,7 @@ struct AppState {
std::array<char, 128> log_filter{};
std::array<char, 96> run_filter{};
std::array<char, 96> generator_filter{};
std::array<char, 96> dataset_filter{};
std::array<char, 256> chat_input{};
std::array<char, 1024> system_prompt{};
std::array<char, 1024> user_prompt{};

View File

@@ -862,8 +862,8 @@ void RenderEmbeddingQualityChart(AppState& state, const DataLoader& loader) {
void RenderAgentThroughputChart(AppState& state, const DataLoader& loader) {
RenderChartHeader(PlotKind::AgentThroughput,
"AGENT THROUGHPUT",
"Real-time task processing rate across the swarm. Higher peaks indicate high-availability periods; the dashed line represents the Swarm Target (1.0k).",
"AGENT WORKLOAD",
"Tasks completed and queue depth per agent from the current data snapshot.",
state);
if (state.agents.empty()) {
@@ -953,8 +953,8 @@ void RenderMissionQueueChart(AppState& state, const DataLoader& loader) {
void RenderLatentSpaceChart(AppState& state, const DataLoader& loader) {
RenderChartHeader(PlotKind::LatentSpace,
"LATENT TOPOLOGY",
"Visualization of the manifold learned by the model. Clusters indicate stable concept representations; voids represent potential logic gaps.",
"EMBEDDING MAP",
"Synthetic layout based on embedding region index; use for rough clustering only.",
state);
const auto& regions = loader.GetEmbeddingRegions();

View File

@@ -37,15 +37,12 @@ CompanionPanels::PanelVisibility CompanionPanels::GetPanelVisibility(PlotKind ki
vis.controls = true;
break;
case PlotKind::AgentUtilization:
case PlotKind::AgentThroughput:
case PlotKind::MountsStatus:
vis.data_quality = true;
vis.inspector = true;
break;
case PlotKind::MissionProgress:
case PlotKind::MissionQueue:
case PlotKind::KnowledgeGraph:
vis.controls = true;
break;
@@ -255,9 +252,10 @@ void CompanionPanels::RenderInspectorPanel(AppState& state, const DataLoader& lo
case PlotKind::EmbeddingQuality: graph_name = "Embedding Quality"; break;
case PlotKind::Rejections: graph_name = "Rejections"; break;
case PlotKind::EvalMetrics: graph_name = "Eval Metrics"; break;
case PlotKind::AgentUtilization: graph_name = "Agent Utilization"; break;
case PlotKind::AgentThroughput: graph_name = "Agent Workload"; break;
case PlotKind::MountsStatus: graph_name = "Mounts Status"; break;
case PlotKind::KnowledgeGraph: graph_name = "Context Graph"; break;
case PlotKind::LatentSpace: graph_name = "Embedding Map"; break;
default: break;
}
ImGui::Text("Graph: %s", graph_name);

View File

@@ -23,10 +23,7 @@ void GraphBrowser::InitializeGraphRegistry() {
{PlotKind::Effectiveness, "Effectiveness", "Generator effectiveness analysis", GraphCategory::Quality, false, true, true, false},
// System Category
{PlotKind::AgentUtilization, "Agent Utilization", "Agent resource usage and activity", GraphCategory::System, false, false, true, true},
{PlotKind::AgentThroughput, "Agent Throughput", "Agent task completion rates", GraphCategory::System, false, false, true, true},
{PlotKind::MissionProgress, "Mission Progress", "Mission completion tracking", GraphCategory::System, false, false, false, false},
{PlotKind::MissionQueue, "Mission Queue", "Mission queue depth over time", GraphCategory::System, false, false, false, false},
{PlotKind::AgentThroughput, "Agent Workload", "Tasks completed and queue depth per agent", GraphCategory::System, false, false, true, true},
{PlotKind::MountsStatus, "Mounts Status", "Filesystem mount status", GraphCategory::System, false, false, true, false},
// Coverage Category
@@ -35,7 +32,7 @@ void GraphBrowser::InitializeGraphRegistry() {
// Embedding Category
{PlotKind::EmbeddingDensity, "Embedding Density", "Embedding space density visualization", GraphCategory::Embedding, false, true, true, true},
{PlotKind::LatentSpace, "Latent Space", "2D latent space projection", GraphCategory::Embedding, false, true, true, true},
{PlotKind::LatentSpace, "Embedding Map", "Synthetic layout from embedding regions", GraphCategory::Embedding, false, true, true, true},
{PlotKind::KnowledgeGraph, "Context Graph", "AFS context and mount relationships", GraphCategory::Embedding, false, false, false, false},
// Optimization Category

View File

@@ -6,6 +6,7 @@
#include <algorithm>
#include <array>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
@@ -33,9 +34,18 @@ std::filesystem::path ResolveHafsScawfulRoot() {
return plugin_path;
}
auto legacy_path = studio::core::FileSystem::ResolvePath("~/src/trunk/scawful/research/afs_scawful");
if (studio::core::FileSystem::Exists(legacy_path)) {
return legacy_path;
const char* trunk_env = std::getenv("TRUNK_ROOT");
if (trunk_env && trunk_env[0] != '\0') {
auto trunk_root = studio::core::FileSystem::ResolvePath(trunk_env);
auto candidate = trunk_root / "scawful" / "research" / "afs_scawful";
if (studio::core::FileSystem::Exists(candidate)) {
return candidate;
}
}
auto fallback_path = studio::core::FileSystem::ResolvePath("~/src/trunk/scawful/research/afs_scawful");
if (studio::core::FileSystem::Exists(fallback_path)) {
return fallback_path;
}
return {};
@@ -219,41 +229,24 @@ static void WriteStringArray(std::ostringstream& output, const std::string& key,
output << "]\n";
}
static bool RunCuratedSummaryBuild(const std::filesystem::path& script_path, std::string* output) {
static bool RunPythonScript(const std::filesystem::path& script_path,
const std::filesystem::path& module_root,
std::string* output) {
if (output) output->clear();
if (!studio::core::FileSystem::Exists(script_path)) {
if (output) *output = "Summary script not found";
if (output) *output = "Script not found";
return false;
}
std::string cmd = "python3 \"" + script_path.string() + "\" 2>&1";
std::string cmd;
if (!module_root.empty()) {
cmd = "AFS_SCAWFUL_ROOT=\"" + module_root.string() + "\" ";
cmd += "PYTHONPATH=\"" + module_root.string() + "\" ";
}
cmd += "python3 \"" + script_path.string() + "\" 2>&1";
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) {
if (output) *output = "Failed to launch summary build";
return false;
}
char buffer[256];
std::ostringstream result;
while (fgets(buffer, sizeof(buffer), pipe)) {
result << buffer;
}
int status = pclose(pipe);
if (output) *output = result.str();
return status == 0;
}
static bool RunResourceIndexBuild(const std::filesystem::path& script_path, std::string* output) {
if (output) output->clear();
if (!studio::core::FileSystem::Exists(script_path)) {
if (output) *output = "Resource index script not found";
return false;
}
std::string cmd = "python3 \"" + script_path.string() + "\" 2>&1";
FILE* pipe = popen(cmd.c_str(), "r");
if (!pipe) {
if (output) *output = "Failed to launch resource index build";
if (output) *output = "Failed to launch script";
return false;
}
@@ -565,7 +558,7 @@ void RenderDatasetPanel(AppState& state, const DataLoader& loader) {
? std::filesystem::current_path() / "rebuild_resource_index.py"
: scawful_root / "scripts" / "rebuild_resource_index.py";
std::string build_output;
bool ok = RunResourceIndexBuild(script_path, &build_output);
bool ok = RunPythonScript(script_path, scawful_root, &build_output);
if (!build_output.empty()) {
resource_status = ok ? "Resource index rebuilt (see logs)" : "Resource index rebuild failed (see logs)";
} else {
@@ -656,13 +649,45 @@ void RenderDatasetPanel(AppState& state, const DataLoader& loader) {
}
if (ImGui::BeginTabItem("Datasets")) {
static std::string dataset_status;
if (!dataset_error.empty()) {
ImGui::TextColored(ImVec4(0.9f, 0.5f, 0.2f, 1.0f), "%s", dataset_error.c_str());
}
ImGui::InputTextWithHint("##DatasetFilter", "Filter by dataset name", state.dataset_filter.data(), state.dataset_filter.size());
ImGui::SameLine();
if (ImGui::Button("Clear##DatasetFilter")) state.dataset_filter[0] = '\0';
ImGui::SameLine();
if (ImGui::Button("Rebuild Dataset Registry")) {
auto scawful_root = ResolveHafsScawfulRoot();
std::filesystem::path script_path = scawful_root.empty()
? std::filesystem::current_path() / "build_dataset_registry.py"
: scawful_root / "scripts" / "build_dataset_registry.py";
std::string build_output;
bool ok = RunPythonScript(script_path, scawful_root, &build_output);
if (!build_output.empty()) {
dataset_status = ok ? "Dataset registry rebuilt (see logs)" : "Dataset registry rebuild failed (see logs)";
} else {
dataset_status = ok ? "Dataset registry rebuilt" : "Dataset registry rebuild failed";
}
state.should_refresh = true;
}
if (!dataset_status.empty()) {
ImGui::SameLine();
ImGui::TextDisabled("%s", dataset_status.c_str());
}
if (dataset_registry.datasets.empty()) {
ImGui::TextDisabled("No dataset registry loaded.");
} else {
std::uint64_t total_size = 0;
for (const auto& dataset : dataset_registry.datasets) {
total_size += dataset.size_bytes;
}
double total_mb = static_cast<double>(total_size) / (1024.0 * 1024.0);
ImGui::Text("Datasets: %zu", dataset_registry.datasets.size());
ImGui::SameLine();
ImGui::TextDisabled("Total size: %.2f MB", total_mb);
if (!dataset_registry.generated_at.empty()) {
ImGui::TextDisabled("Generated at: %s", dataset_registry.generated_at.c_str());
}
@@ -676,10 +701,17 @@ void RenderDatasetPanel(AppState& state, const DataLoader& loader) {
ImGui::TableSetupColumn("Updated", ImGuiTableColumnFlags_WidthStretch, 1.1f);
ImGui::TableHeadersRow();
for (const auto& dataset : dataset_registry.datasets) {
for (size_t i = 0; i < dataset_registry.datasets.size(); ++i) {
const auto& dataset = dataset_registry.datasets[i];
if (!ContainsInsensitive(dataset.name, state.dataset_filter.data())) {
continue;
}
ImGui::TableNextRow();
ImGui::TableNextColumn();
ImGui::Text("%s", dataset.name.c_str());
bool selected = static_cast<int>(i) == state.selected_dataset_index;
if (ImGui::Selectable(dataset.name.c_str(), selected, ImGuiSelectableFlags_SpanAllColumns)) {
state.selected_dataset_index = static_cast<int>(i);
}
if (ImGui::IsItemHovered() && !dataset.path.empty()) {
ImGui::BeginTooltip();
ImGui::Text("%s", dataset.path.c_str());
@@ -695,6 +727,28 @@ void RenderDatasetPanel(AppState& state, const DataLoader& loader) {
}
ImGui::EndTable();
}
ImGui::Separator();
if (state.selected_dataset_index >= 0 &&
state.selected_dataset_index < static_cast<int>(dataset_registry.datasets.size())) {
const auto& selected = dataset_registry.datasets[state.selected_dataset_index];
ImGui::TextDisabled("Selected Dataset");
ImGui::Text("%s", selected.name.c_str());
ImGui::TextDisabled("%s", selected.path.empty() ? "-" : selected.path.c_str());
ImGui::Text("Files: %zu", selected.files.size());
ImGui::BeginChild("DatasetFiles", ImVec2(0, 120), true);
size_t max_files = 12;
for (size_t i = 0; i < selected.files.size() && i < max_files; ++i) {
ImGui::BulletText("%s", selected.files[i].c_str());
}
if (selected.files.size() > max_files) {
ImGui::TextDisabled("... and %zu more", selected.files.size() - max_files);
}
ImGui::EndChild();
} else {
ImGui::TextDisabled("Select a dataset to view details.");
}
}
ImGui::EndTabItem();
@@ -861,7 +915,7 @@ void RenderDatasetPanel(AppState& state, const DataLoader& loader) {
std::filesystem::path script_path = override_path.parent_path().parent_path();
script_path /= "scripts/build_curated_hacks_summary.py";
std::string build_output;
bool ok = RunCuratedSummaryBuild(script_path, &build_output);
bool ok = RunPythonScript(script_path, scawful_root, &build_output);
overrides_status = ok ? "Saved overrides and rebuilt summary" : "Saved overrides, rebuild failed";
if (!build_output.empty()) {
overrides_status += " (see logs)";

View File

@@ -234,17 +234,14 @@ const std::vector<PlotOption>& PlotOptions() {
{PlotKind::LossVsSamples, "Loss vs Samples"},
{PlotKind::DomainCoverage, "Domain Coverage"},
{PlotKind::EmbeddingQuality, "Embedding Quality"},
{PlotKind::AgentThroughput, "Agent Throughput"},
{PlotKind::MissionQueue, "Mission Queue"},
{PlotKind::AgentThroughput, "Agent Workload"},
{PlotKind::QualityDirection, "Quality Direction"},
{PlotKind::GeneratorMix, "Generator Mix"},
{PlotKind::EmbeddingDensity, "Embedding Density"},
{PlotKind::AgentUtilization, "Agent Utilization"},
{PlotKind::MissionProgress, "Mission Progress"},
{PlotKind::EvalMetrics, "Eval Metrics"},
{PlotKind::Rejections, "Rejection Reasons"},
{PlotKind::KnowledgeGraph, "Context Graph"},
{PlotKind::LatentSpace, "Latent Space"},
{PlotKind::LatentSpace, "Embedding Map"},
{PlotKind::Effectiveness, "Domain Effectiveness"},
{PlotKind::Thresholds, "Threshold Sensitivity"},
{PlotKind::MountsStatus, "Local Mounts Status"},

View File

@@ -1,6 +1,7 @@
#include "sample_review.h"
#include <imgui.h>
#include <algorithm>
#include <cstdlib>
#include <fstream>
#include <sstream>
#include <filesystem>
@@ -12,6 +13,28 @@ namespace viz {
namespace {
std::filesystem::path ResolveContextRoot() {
const char* env_root = std::getenv("AFS_CONTEXT_ROOT");
if (env_root && env_root[0] != '\0') {
auto path = studio::core::FileSystem::ResolvePath(env_root);
if (studio::core::FileSystem::Exists(path)) {
return path;
}
}
auto preferred = studio::core::FileSystem::ResolvePath("~/src/context");
if (studio::core::FileSystem::Exists(preferred)) {
return preferred;
}
auto fallback = studio::core::FileSystem::ResolvePath("~/.context");
if (studio::core::FileSystem::Exists(fallback)) {
return fallback;
}
return preferred;
}
TrainingSample ParseSampleLine(const std::string& line, bool is_rejected = false) {
TrainingSample sample;
sample.is_rejected = is_rejected;
@@ -334,7 +357,7 @@ void SampleReviewWidget::LoadContextFiles() {
context_files_.clear();
// Load user's ASM files from alttp disassembly
auto alttp_path = std::filesystem::path(std::getenv("HOME")) / ".context" / "knowledge" / "alttp";
auto alttp_path = ResolveContextRoot() / "knowledge" / "alttp";
if (studio::core::FileSystem::Exists(alttp_path)) {
try {

View File

@@ -106,9 +106,14 @@ bool TrainingStatusWidget::FetchHealthData() {
if (env_root && env_root[0] != '\0') {
root = env_root;
} else {
const char* home = std::getenv("HOME");
if (home && home[0] != '\0') {
root = std::string(home) + "/src/trunk/scawful/research/afs";
const char* trunk_root = std::getenv("TRUNK_ROOT");
if (trunk_root && trunk_root[0] != '\0') {
root = std::string(trunk_root) + "/scawful/research/afs";
} else {
const char* home = std::getenv("HOME");
if (home && home[0] != '\0') {
root = std::string(home) + "/src/trunk/scawful/research/afs";
}
}
}