PIPS-demo / src /pips /templates /index_modular.html
steinad's picture
Initial commit
adca48b
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>PIPS - Per-Instance Program Synthesis</title>
<!-- External Dependencies -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.7.2/socket.io.js"></script>
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/plugins/autoloader/prism-autoloader.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/themes/prism-tomorrow.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700;800;900&family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
<link href="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.29.1/feather.min.css" rel="stylesheet">
<!-- Modular CSS -->
<link href="{{ url_for('static', filename='css/main.css') }}" rel="stylesheet">
<link href="{{ url_for('static', filename='css/components/feedback.css') }}" rel="stylesheet">
</head>
<body>
<div class="container">
<!-- Left Panel - Input -->
<div class="left-panel">
<div class="header">
<h1>PIPS</h1>
<p>Per-Instance Program Synthesis</p>
</div>
<div class="input-section">
<!-- New Session Button -->
<div class="form-group">
<button id="newSessionBtn" class="btn btn-outline">
<i data-feather="plus" style="width: 16px; height: 16px;"></i>
Start New Session
</button>
</div>
<!-- PIPS Mode Selection (iOS-style switch) -->
<div class="form-group">
<label for="questionInput" class="form-label">Problem Description</label>
<textarea id="questionInput" placeholder="Enter your problem here... (e.g., 'What is the square root of 144?', 'Solve this math puzzle', etc.)"></textarea>
</div>
<!-- PIPS Mode Selection (iOS-style switch) -->
<div class="form-group">
<label class="form-label">PIPS Mode</label>
<div class="ios-switch-container">
<div class="ios-switch-wrapper">
<input type="checkbox" id="pipsModeSwitch" class="ios-switch-input">
<label for="pipsModeSwitch" class="ios-switch-label">
<span class="ios-switch-slider">
<span class="ios-switch-text ios-switch-text-left">Interactive</span>
<span class="ios-switch-text ios-switch-text-right">Agent</span>
</span>
</label>
</div>
<div class="mode-description">
<span id="modeDescription">Automatic solving without user intervention</span>
</div>
</div>
<!-- Hidden radio buttons for backend compatibility -->
<div style="display: none;">
<input type="radio" name="pipsMode" value="AGENT" id="pipsModeAgent" checked>
<input type="radio" name="pipsMode" value="INTERACTIVE" id="pipsModeInteractive">
</div>
</div>
<!-- Custom Rules (for critic) -->
<div class="form-group">
<label for="customRules" class="form-label">
Per-Session Rules for AI Critic
<small class="form-help-inline">(optional)</small>
</label>
<textarea id="customRules"
class="custom-rules-input"
placeholder="Add rules specific to this session... (e.g., 'Must use only numpy functions for this problem', 'Optimize for memory usage', etc.)"
rows="3"></textarea>
<div class="form-help">These rules apply only to the current session and will be cleared when starting a new session</div>
</div>
<div class="form-group">
<label class="form-label">Attach Image (optional)</label>
<div class="image-upload">
<label for="imageInput" class="image-upload-btn">
<i data-feather="image" style="width: 16px; height: 16px;"></i>
Choose Image
</label>
<div class="image-upload-text">
Or drag and drop an image here
</div>
<input type="file" id="imageInput" accept="image/*">
<img id="imagePreview" class="image-preview" style="display: none;">
</div>
<div class="form-help">Upload an image to include visual context with your problem</div>
</div>
<!-- Sessions Management Section -->
<div class="form-group">
<div class="sessions-header">
<label class="form-label">
<i data-feather="clock" style="width: 16px; height: 16px; margin-right: 8px;"></i>
Session History
</label>
<button type="button" class="sessions-toggle" id="sessionsToggle">
<i data-feather="chevron-down" style="width: 16px; height: 16px;"></i>
</button>
</div>
<div class="sessions-container" id="sessionsContainer">
<div class="sessions-list" id="sessionsList">
<!-- Sessions will be dynamically populated -->
</div>
<div class="sessions-actions">
<button type="button" class="btn-session-action" id="clearSessionsBtn">
<i data-feather="trash-2" style="width: 14px; height: 14px;"></i>
Clear All
</button>
<button type="button" class="btn-session-action" id="importSessionsBtn">
<i data-feather="upload" style="width: 14px; height: 14px;"></i>
Import
</button>
<button type="button" class="btn-session-action" id="exportSessionsBtn">
<i data-feather="download" style="width: 14px; height: 14px;"></i>
Export
</button>
<input type="file" id="importSessionsInput" accept=".json" style="display: none;">
</div>
</div>
<div class="form-help">Switch between past and current problem-solving sessions</div>
</div>
<div class="button-group">
<button id="solveBtn" class="btn btn-primary">
<i data-feather="play" style="width: 16px; height: 16px;"></i>
Solve Problem
</button>
<button id="interruptBtn" class="btn btn-danger" style="display: none;">
<i data-feather="stop-circle" style="width: 16px; height: 16px;"></i>
Stop
</button>
<button id="settingsBtn" class="btn btn-secondary">
<i data-feather="settings" style="width: 16px; height: 16px;"></i>
Settings
</button>
</div>
</div>
</div>
<!-- Right Panel - Chat -->
<div class="right-panel">
<div class="status-bar" id="statusIndicator">
Ready to solve problems
</div>
<div class="progress-container" id="progressContainer">
<div class="progress-bar">
<div class="progress-fill" id="progressFill"></div>
</div>
</div>
<div class="chat-area" id="chatArea">
<div class="chat-message">
<div class="message-header">
<div class="message-avatar avatar-pips">P</div>
<span class="message-sender">PIPS System</span>
</div>
<div class="message-content">
Welcome to PIPS! Enter a problem in the left panel and click "Solve Problem" to get started.
Don't forget to configure your model settings first.
<br><br>
<strong>New to PIPS?</strong> Check out the curated example sessions in the Session History panel on the left.
</div>
</div>
</div>
<!-- Container for interactive feedback panels and final artifacts -->
<div class="chat-container" id="chat-container"></div>
<div class="footer">
<div class="footer-info">
<span id="sessionInfo">Session: Not connected</span>
</div>
<button id="downloadBtn" class="btn btn-secondary">
<i data-feather="file-text" style="width: 16px; height: 16px;"></i>
Download PDF
</button>
</div>
</div>
</div>
<!-- Settings Modal -->
<div id="settingsModal" class="modal">
<div class="modal-content">
<div class="modal-header">
<h2 class="modal-title">Settings</h2>
<span class="close">&times;</span>
</div>
<div class="modal-body">
<!-- Settings Tabs -->
<div class="settings-tabs">
<button type="button" class="tab-button active" data-tab="general">General</button>
<button type="button" class="tab-button" data-tab="models">Models</button>
<button type="button" class="tab-button" data-tab="rules">Custom Rules</button>
</div>
<form id="settingsForm">
<!-- General Settings Tab -->
<div class="tab-content active" id="general-tab">
<div class="form-group">
<label for="openaiApiKeyInput">OpenAI API Key</label>
<input type="password" id="openaiApiKeyInput" placeholder="Enter your OpenAI API key (for GPT models)">
</div>
<div class="form-group">
<label for="googleApiKeyInput">Google API Key</label>
<input type="password" id="googleApiKeyInput" placeholder="Enter your Google API key (for Gemini models)">
</div>
<div class="form-group">
<label for="anthropicApiKeyInput">Anthropic API Key</label>
<input type="password" id="anthropicApiKeyInput" placeholder="Enter your Anthropic API key (for Claude models)">
</div>
<div class="form-group">
<label>Problem Solving Method</label>
<div class="form-help">
PIPS now selects between iterative code generation and chain-of-thought reasoning automatically for each problem.
</div>
</div>
<div class="form-group">
<label for="maxIterations">Max Iterations</label>
<input type="number" id="maxIterations" min="1" max="20" value="{{ default_settings.max_iterations }}">
</div>
<div class="form-group">
<label for="temperature">Temperature</label>
<input type="number" id="temperature" min="0" max="2" step="0.1" value="{{ default_settings.temperature }}">
</div>
<div class="form-group">
<label for="maxTokens">Max Tokens</label>
<input type="number" id="maxTokens" min="512" max="32768" step="512" value="{{ default_settings.max_tokens }}">
</div>
<div class="form-group">
<label for="maxExecutionTime">Max Code Execution Time (seconds)</label>
<input type="number" id="maxExecutionTime" min="1" max="60" value="{{ default_settings.max_execution_time }}">
<small class="form-help">Maximum time to wait for code execution before timing out</small>
</div>
<div class="form-group">
<label>Session Management</label>
<button type="button" id="clearAllSessionsBtn" class="btn btn-danger" style="width: 100%;">
<i data-feather="trash-2" style="width: 16px; height: 16px;"></i>
Clear All Sessions
</button>
<small class="form-help">Permanently delete all session history and chat data</small>
</div>
</div>
<!-- Models Settings Tab -->
<div class="tab-content" id="models-tab">
<div class="form-group">
<label for="generatorModelSelect">Code Generator Model</label>
<select id="generatorModelSelect">
{% for model_id, model_name in available_models.items() %}
<option value="{{ model_id }}" {% if model_id == default_settings.model %}selected{% endif %}>
{{ model_name }}
</option>
{% endfor %}
</select>
<small class="form-help">Model used for generating code solutions</small>
</div>
<div class="form-group">
<label for="criticModelSelect">Code Critic Model</label>
<select id="criticModelSelect">
{% for model_id, model_name in available_models.items() %}
<option value="{{ model_id }}" {% if model_id == default_settings.model %}selected{% endif %}>
{{ model_name }}
</option>
{% endfor %}
</select>
<small class="form-help">Model used for reviewing and critiquing generated code</small>
</div>
<div class="form-help">
<p><strong>Tip:</strong> You can use different models for generation and criticism. For example, use a fast model for generation and a more powerful model for criticism.</p>
</div>
</div>
<!-- Custom Rules Tab -->
<div class="tab-content" id="rules-tab">
<div class="form-group">
<label for="customRulesSettings">Global Rules for AI Critic</label>
<textarea id="customRulesSettings"
class="custom-rules-input"
rows="8"
placeholder="Add global rules that apply to all sessions...
Examples:
• Must use only numpy functions for mathematical operations
• Code should be optimized for performance over readability
• Include comprehensive error handling
• Follow PEP 8 style guidelines strictly
• Use type hints for all function parameters"></textarea>
<small class="form-help">These global rules persist across all sessions and are combined with any per-session rules you specify in the main interface.</small>
</div>
<div class="form-help">
<p><strong>How it works:</strong> Global rules are saved and applied to all sessions, while per-session rules (from the main interface) apply only to the current session.</p>
<p>The critic will use both types of rules along with its built-in knowledge when evaluating generated code.</p>
</div>
</div>
<button type="submit" class="btn btn-primary" style="width: 100%;">
<i data-feather="check" style="width: 16px; height: 16px;"></i>
Save Settings
</button>
</form>
</div>
</div>
</div>
<!-- Feather Icons -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/feather-icons/4.29.1/feather.min.js"></script>
<!-- PDF Generation -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<!-- Modular JavaScript -->
<script src="{{ url_for('static', filename='js/ui/interactive-feedback.js') }}"></script>
<script type="module" src="{{ url_for('static', filename='js/main.js') }}"></script>
</body>
</html>