Files
whetstone_DSL/editor/src/AgentChatPanelModel.h

117 lines
4.1 KiB
C
Raw Normal View History

#pragma once
// Step 624: Agent Chat Panel model
#include "AgentToolCallVisualization.h"
#include "AgentMutationPreview.h"
#include "AgentMutationApproval.h"
2026-02-17 21:21:20 -07:00
#include <cstddef>
#include <cctype>
#include <string>
#include <vector>
enum class AgentChatRole {
User,
Assistant,
Tool
};
struct AgentChatMessage {
AgentChatRole role = AgentChatRole::User;
std::string content;
std::string timestamp;
};
struct AgentChatState {
std::vector<AgentChatMessage> messages;
std::vector<AgentToolCallView> toolCalls;
std::vector<AgentMutationPreview> mutationPreviews;
std::vector<MutationApprovalRecord> mutationApprovals;
std::string systemContext;
std::string draftInput;
2026-02-17 21:21:20 -07:00
std::string loadedProjectFile;
std::size_t persistedMessageCount = 0;
bool sessionLoaded = false;
bool autoScroll = true;
bool open = false;
};
class AgentChatPanelModel {
public:
static bool sendUserMessage(AgentChatState* state, const std::string& timestamp) {
if (!state) return false;
std::string text = trimCopy(state->draftInput);
if (text.empty()) return false;
state->messages.push_back({AgentChatRole::User, text, timestamp});
state->draftInput.clear();
state->autoScroll = true;
return true;
}
static void addAssistantMessage(AgentChatState* state,
const std::string& content,
const std::string& timestamp) {
if (!state) return;
state->messages.push_back({AgentChatRole::Assistant, content, timestamp});
state->autoScroll = true;
}
static void addToolMessage(AgentChatState* state,
const std::string& content,
const std::string& timestamp) {
if (!state) return;
state->messages.push_back({AgentChatRole::Tool, content, timestamp});
state->autoScroll = true;
}
static void addToolCall(AgentChatState* state,
const std::string& toolName,
const json& input,
const json& output,
const std::string& timestamp) {
if (!state) return;
AgentToolCallView view = AgentToolCallVisualization::build(toolName, input, output);
state->toolCalls.push_back(view);
state->messages.push_back({AgentChatRole::Tool,
AgentToolCallVisualization::inlineLabel(view),
timestamp});
state->autoScroll = true;
}
static void addMutationPreview(AgentChatState* state,
const std::string& previewId,
const std::string& mutationJson,
const std::string& beforeCode,
const std::string& afterCode,
const std::string& timestamp) {
if (!state) return;
AgentMutationPreview preview = AgentMutationPreviewBuilder::build(
previewId, mutationJson, beforeCode, afterCode);
state->mutationPreviews.push_back(preview);
std::string label = std::string("[PREVIEW] ") + previewId +
(preview.hasChanges ? " (changes)" : " (no changes)");
state->messages.push_back({AgentChatRole::Tool, label, timestamp});
state->autoScroll = true;
}
static const char* roleLabel(AgentChatRole role) {
if (role == AgentChatRole::User) return "user";
if (role == AgentChatRole::Assistant) return "assistant";
return "tool";
}
static std::string trimCopy(const std::string& value) {
std::size_t begin = 0;
while (begin < value.size() &&
std::isspace(static_cast<unsigned char>(value[begin]))) {
++begin;
}
std::size_t end = value.size();
while (end > begin &&
std::isspace(static_cast<unsigned char>(value[end - 1]))) {
--end;
}
return value.substr(begin, end - begin);
}
};