@prism-lang/repl
Version:
Interactive REPL for Prism language
318 lines (302 loc) ⢠10.7 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.PrismREPL = void 0;
exports.runRepl = runRepl;
const core_1 = require("@prism-lang/core");
const llm_1 = require("@prism-lang/llm");
class PrismREPL {
runtime;
history = [];
startTime;
variables = new Map();
constructor() {
this.runtime = new core_1.Runtime();
this.startTime = new Date();
}
registerLLMProvider(name, provider) {
this.runtime.registerLLMProvider(name, provider);
}
setDefaultLLMProvider(name) {
this.runtime.setDefaultLLMProvider(name);
}
async evaluate(input) {
const trimmedInput = input.trim();
// Handle REPL commands
if (trimmedInput.startsWith(':')) {
return this.handleCommand(trimmedInput);
}
if (!trimmedInput) {
return { success: true, value: '', type: 'empty' };
}
try {
// Parse the input
const program = (0, core_1.parse)(trimmedInput);
// Execute the program
const result = await this.runtime.execute(program);
// Update variables tracking (simplified approach)
this.trackVariablesFromInput(trimmedInput, result);
// Format the result for display
const formattedResult = this.formatValue(result);
const replResult = {
success: true,
value: formattedResult.value,
type: formattedResult.type,
};
// Add to history
this.addToHistory(trimmedInput, replResult);
return replResult;
}
catch (error) {
const errorMessage = error instanceof Error ? error.message : String(error);
const replResult = {
success: false,
error: errorMessage,
};
// Add to history
this.addToHistory(trimmedInput, replResult);
return replResult;
}
}
handleCommand(command) {
const cmd = command.toLowerCase();
switch (cmd) {
case ':help':
return {
success: true,
value: this.getHelpText(),
type: 'help',
};
case ':vars':
return {
success: true,
value: this.getVariablesText(),
type: 'vars',
};
case ':clear':
this.clearSession();
return {
success: true,
value: 'Session cleared. All variables and history removed.',
type: 'info',
};
case ':history':
return {
success: true,
value: this.getHistoryText(),
type: 'history',
};
case ':stats':
return {
success: true,
value: this.getStatsText(),
type: 'stats',
};
case ':llm':
return {
success: true,
value: this.getLLMText(),
type: 'llm',
};
case ':exit':
case ':quit':
return {
success: true,
value: 'Goodbye! Thanks for using Prism! š',
type: 'exit',
shouldExit: true,
};
default:
return {
success: false,
error: `Unknown command: ${command}. Type :help for available commands.`,
};
}
}
formatValue(value) {
if (value instanceof core_1.NumberValue) {
return { value: value.value.toString(), type: 'number' };
}
if (value instanceof core_1.StringValue) {
return { value: value.value, type: 'string' };
}
if (value instanceof core_1.BooleanValue) {
return { value: value.value.toString(), type: 'boolean' };
}
if (value instanceof core_1.ConfidenceValue) {
const innerResult = this.formatValue(value.value);
return {
value: `${innerResult.value} (~${(value.confidence.value * 100).toFixed(1)}%)`,
type: 'confident'
};
}
return { value: value.toString(), type: value.type };
}
trackVariablesFromInput(input, result) {
// Simple pattern matching for assignments
const assignmentMatch = input.match(/^\s*(\w+)\s*=/);
if (assignmentMatch) {
const variableName = assignmentMatch[1];
this.variables.set(variableName, result);
}
}
addToHistory(input, result) {
this.history.push({
input,
result,
timestamp: new Date(),
});
// Keep history limited to last 100 entries
if (this.history.length > 100) {
this.history.shift();
}
}
clearSession() {
this.runtime = new core_1.Runtime();
this.variables.clear();
this.history = [];
// Re-register any LLM providers that were set up
// Note: In a real implementation, we'd want to preserve provider configuration
}
getHelpText() {
return `
š Prism REPL Commands š
Basic Usage:
Simply type Prism expressions and press Enter
Example: 2 + 3
Example: llm("Hello AI!")
Example: x = 42 ~> 0.9
Commands:
:help - Show this help message
:vars - Show all defined variables
:clear - Clear session (reset all variables)
:history - Show evaluation history
:stats - Show session statistics
:llm - Show LLM provider information
:exit - Exit the REPL
Language Features:
⢠Arithmetic: +, -, *, /
⢠Comparison: >, <, >=, <=, ==, !=
⢠Confidence: value ~> confidence_level
⢠LLM calls: llm("your prompt here")
⢠Variables: name = value
⢠Control flow: if/else, uncertain if
⢠Contexts: in context Name { ... }
Examples:
result = llm("What is AI?")
uncertain if (result ~> 0.8) {
high { confident_response = "High confidence!" }
low { uncertain_response = "Need more info" }
}
in context Research {
findings = llm("Research topic: " + topic)
}
Happy coding with Prism! š
`.trim();
}
getVariablesText() {
if (this.variables.size === 0) {
return 'No variables defined in current session.';
}
const varLines = ['š Current Variables:'];
for (const [name, value] of this.variables) {
const formatted = this.formatValue(value);
varLines.push(` ${name}: ${formatted.value} (${formatted.type})`);
}
return varLines.join('\n');
}
getHistoryText() {
if (this.history.length === 0) {
return 'No evaluation history.';
}
const historyLines = ['š Evaluation History (last 10):'];
// Show last 10 entries
const recentHistory = this.history.slice(-10);
recentHistory.forEach((entry, index) => {
const timestamp = entry.timestamp.toLocaleTimeString();
const status = entry.result.success ? 'ā
' : 'ā';
historyLines.push(` ${index + 1}. [${timestamp}] ${status} ${entry.input}`);
if (entry.result.success) {
historyLines.push(` ā ${entry.result.value}`);
}
else {
historyLines.push(` ā Error: ${entry.result.error}`);
}
});
return historyLines.join('\n');
}
getStatsText() {
const stats = this.getSessionStats();
return `
š Session Statistics
ā±ļø Session Duration: ${Math.floor(stats.uptime / 1000)}s
šÆ Total Evaluations: ${stats.totalEvaluations}
ā
Successful: ${stats.successfulEvaluations}
ā Errors: ${stats.errors}
š Success Rate: ${stats.totalEvaluations > 0 ? ((stats.successfulEvaluations / stats.totalEvaluations) * 100).toFixed(1) : 0}%
šļø Variables Defined: ${stats.variablesCount}
š Started: ${stats.startTime.toLocaleString()}
`.trim();
}
getLLMText() {
const availableProviders = llm_1.LLMConfigManager.getAvailableProviders();
const defaultProvider = llm_1.LLMConfigManager.getDefaultProvider();
const currentProvider = this.runtime.getDefaultLLMProvider();
const configStatus = llm_1.LLMConfigManager.getConfigStatus();
return `
š¤ LLM Provider Information
Available Providers: ${availableProviders.join(', ')}
Default Provider: ${defaultProvider}
Current Provider: ${currentProvider || 'none'}
š Configuration Status:
${configStatus.map(item => {
const current = item.provider === currentProvider ? ' ā current' : '';
const details = item.details ? `\n ${item.details}` : '';
return ` ⢠${item.provider}: ${item.status}${current}${details}`;
}).join('\n')}
Configuration Help:
${llm_1.LLMConfigManager.showConfigHelp()}
Usage in Prism:
result = llm("Your prompt here")
response = llm("Question", { model: "claude-3-sonnet", temperature: 0.5 })
`.trim();
}
getHistory() {
return [...this.history];
}
getSessionStats() {
const now = new Date();
const successfulEvaluations = this.history.filter(h => h.result.success).length;
return {
totalEvaluations: this.history.length,
successfulEvaluations,
errors: this.history.length - successfulEvaluations,
variablesCount: this.variables.size,
startTime: this.startTime,
uptime: now.getTime() - this.startTime.getTime(),
};
}
// Method to create a formatted welcome message
getWelcomeMessage() {
return `
š Welcome to Prism REPL! š
Prism is a programming language designed for LLM orchestration and AI-aware computing.
Features available:
⢠š§ Confidence-aware programming with ~> operator
⢠š¤ Built-in LLM integration with llm() function
⢠š Context-aware execution environments
⢠š Uncertainty handling with uncertain if statements
⢠šÆ Agent coordination and management
Type :help for commands or start coding!
Examples:
ā 2 + 3
ā llm("Hello AI!")
ā x = 42 ~> 0.9
Ready to explore the future of AI programming? Let's go! š
`.trim();
}
}
exports.PrismREPL = PrismREPL;
function runRepl() {
return new PrismREPL();
}
//# sourceMappingURL=repl.js.map
;