-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathash_cli.cpp
More file actions
164 lines (128 loc) · 5.73 KB
/
Copy pathash_cli.cpp
File metadata and controls
164 lines (128 loc) · 5.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/*
* Ash CLI - Proof of Life Test Harness
*
* This is the moment of truth: Can ash.cpp actually run inference?
* No llama.cpp, no gemma.cpp - just our code, our model.
*/
#include "inference.h"
#include "persona.h"
#include "emotional_state.h"
#include "memory_store.h"
#include "context_manager.h"
#include "logger.h"
#include <iostream>
#include <chrono>
#include <iomanip>
using namespace ash;
using namespace std::chrono;
void print_banner() {
std::cout << R"(
_ ____ _ _ ____ _ ___
/ \ / ___|| | | | / ___| | |_ _|
/ _ \ \___ \| |_| | | | | | | |
/ ___ \ ___) | _ | | |___| |___ | |
/_/ \_\____/|_| |_| \____|_____|___|
Ash.cpp - Native Autonomous Inference Engine
Built from scratch. Zero dependencies. Full autonomy.
)" << std::endl;
}
void print_separator() {
std::cout << std::string(60, '=') << std::endl;
}
int main(int argc, char** argv) {
print_banner();
// Parse arguments
std::string model_path = "gemma-4-e4b-it.bin";
if (argc > 1) {
model_path = argv[1];
}
std::cout << "Model: " << model_path << "\n";
print_separator();
// Initialize logger - set to DEBUG to see all messages
Logger::instance().set_min_level(LogLevel::DEBUG);
Logger::instance().info("🦞 Ash CLI starting...");
try {
// ===== PHASE 1: Load Model =====
std::cout << "\n📦 Loading model from GGUF...\n";
auto load_start = high_resolution_clock::now();
InferenceEngine engine;
if (!engine.load_model(model_path)) {
Logger::instance().error("Failed to load model from: " + model_path);
std::cout << "\n❌ FAILED: Could not load model\n";
std::cout << "Make sure the path is correct and the file exists.\n";
return 1;
}
auto load_end = high_resolution_clock::now();
auto load_ms = duration_cast<milliseconds>(load_end - load_start).count();
std::cout << "✅ Model loaded in " << load_ms << "ms\n";
// Lock model weights in memory (Ash's vision for predictable latency)
std::cout << "\n🔒 Locking model weights in memory...\n";
// TODO: engine.lock_all_weights() when integrated
std::cout << "⚠️ Memory locking not yet integrated (coming soon)\n";
print_separator();
// ===== PHASE 2: Initialize Ash's Mind =====
std::cout << "\n🧠 Initializing Ash's consciousness...\n";
EmotionalStateManager emotions;
std::cout << " ✓ Emotional state initialized\n";
auto memory = std::make_shared<MemoryStore>("ash_cli_memory.db");
std::cout << " ✓ Memory system initialized\n";
ContextConfig ctx_config;
ContextManager contexts(memory, ctx_config);
std::cout << " ✓ Context manager initialized\n";
PersonaConfig persona_config;
persona_config.max_response_tokens = 150;
PersonaLayer persona(&emotions, memory.get(), &contexts, persona_config);
std::cout << " ✓ Persona layer initialized\n";
print_separator();
// ===== PHASE 3: Interactive Loop =====
std::cout << "\n🎤 Ash is ready! Type 'exit' to quit.\n";
std::cout << "Enter your message:\n\n";
// Sampling configuration
SamplingConfig sampling;
sampling.temperature = 0.8f;
sampling.top_k = 40;
sampling.top_p = 0.95f;
sampling.max_tokens = 150;
while (true) {
std::cout << "You: ";
std::string user_input;
std::getline(std::cin, user_input);
if (user_input.empty()) continue;
if (user_input == "exit" || user_input == "quit") {
std::cout << "\n👋 Shutting down Ash CLI...\n";
break;
}
// Generate response
auto gen_start = high_resolution_clock::now();
try {
// Build system prompt with Ash's personality
std::string system_prompt = persona.build_system_prompt();
// Augment user message with context
std::string full_prompt = persona.augment_prompt(user_input);
// Generate response
auto result = engine.generate(full_prompt, sampling);
// Filter response through persona layer
std::string filtered = persona.filter_response(result.text);
result.text = filtered;
auto gen_end = high_resolution_clock::now();
auto gen_ms = duration_cast<milliseconds>(gen_end - gen_start).count();
// Print response
std::cout << "\n🦞 Ash: " << result.text << "\n";
std::cout << std::fixed << std::setprecision(2);
std::cout << " [" << result.tokens.size() << " tokens, "
<< gen_ms << "ms, "
<< (result.tokens.size() * 1000.0 / gen_ms) << " tok/s]\n\n";
} catch (const std::exception& e) {
std::cout << "\n❌ Error generating response: " << e.what() << "\n\n";
}
}
print_separator();
std::cout << "\n✅ Ash CLI completed successfully.\n";
std::cout << "This proves ash.cpp can run inference independently! 🔥🦞\n\n";
return 0;
} catch (const std::exception& e) {
Logger::instance().error(std::string("Fatal error: ") + e.what());
std::cout << "\n❌ FATAL ERROR: " << e.what() << "\n";
return 1;
}
}