New web interface, move llm engine to separate process
This commit is contained in:
215
web/src/components/Memory/entries/RepeatEntry.tsx
Normal file
215
web/src/components/Memory/entries/RepeatEntry.tsx
Normal file
@@ -0,0 +1,215 @@
|
||||
import React from 'react';
|
||||
import { BaseEntry } from './BaseEntry';
|
||||
import { ScriptEntryData } from '../../../types/entries';
|
||||
|
||||
interface RepeatEntryProps {
|
||||
entry: ScriptEntryData;
|
||||
onDelete: (id: string) => void;
|
||||
onUpdate: (id: string) => void;
|
||||
onReset: (id: string) => void;
|
||||
onSave: (id: string, data: ScriptEntryData) => Promise<void>;
|
||||
}
|
||||
|
||||
const RepeatEntry: React.FC<RepeatEntryProps> = ({
|
||||
entry,
|
||||
onDelete,
|
||||
onUpdate,
|
||||
onReset,
|
||||
onSave
|
||||
}) => {
|
||||
const renderContent = (data: ScriptEntryData) => (
|
||||
<div className="space-y-3">
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Script:</span>
|
||||
<pre className="mt-1 text-sm text-gray-900 bg-gray-50 p-2 rounded whitespace-pre-wrap overflow-x-auto">{data.script || ''}</pre>
|
||||
</div>
|
||||
|
||||
{data.timeout !== undefined && data.timeout !== null && (
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Timeout:</span>
|
||||
<span className="ml-2 text-sm text-gray-900">{data.timeout} seconds</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data.limit !== undefined && data.limit !== null && (
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Memory Limit:</span>
|
||||
<span className="ml-2 text-sm text-gray-900">{data.limit} bytes</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data.stdout && (
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Standard Output:</span>
|
||||
<pre className="mt-1 text-sm text-gray-900 bg-gray-50 p-2 rounded overflow-x-auto max-h-40">{data.stdout}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data.stderr && (
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Standard Error:</span>
|
||||
<pre className="mt-1 text-sm text-gray-900 bg-red-50 p-2 rounded overflow-x-auto max-h-40">{data.stderr}</pre>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{data.exit_code !== null && data.exit_code !== undefined && (
|
||||
<div>
|
||||
<span className="text-sm font-medium text-gray-700">Exit Code:</span>
|
||||
<span className="ml-2 text-sm text-gray-900">{data.exit_code}</span>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<span className="text-sm text-gray-700">
|
||||
{data.timed_out ? '⚠ Timed Out' : '✓ Within Timeout'}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const renderEditForm = (
|
||||
data: ScriptEntryData,
|
||||
onChange: (data: ScriptEntryData) => void,
|
||||
isLoading: boolean
|
||||
) => (
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Script</label>
|
||||
<textarea
|
||||
value={data.script || ''}
|
||||
onChange={e => onChange({ ...data, script: e.target.value })}
|
||||
className="w-full p-2 border rounded font-mono text-sm resize-vertical"
|
||||
rows={4}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center mb-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={data.timeout !== null && data.timeout !== undefined}
|
||||
onChange={e => onChange({
|
||||
...data,
|
||||
timeout: e.target.checked ? 1.0 : null
|
||||
})}
|
||||
className="rounded border-gray-300"
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<label className="ml-2 text-sm font-medium text-gray-700">Custom Timeout (seconds)</label>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
value={data.timeout !== null && data.timeout !== undefined ? data.timeout : ''}
|
||||
onChange={e => onChange({
|
||||
...data,
|
||||
timeout: e.target.value ? parseFloat(e.target.value) : null
|
||||
})}
|
||||
className="w-full p-2 border rounded text-sm disabled:bg-gray-100"
|
||||
step="0.1"
|
||||
min="0"
|
||||
disabled={isLoading || data.timeout === null || data.timeout === undefined}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center mb-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={data.limit !== null && data.limit !== undefined}
|
||||
onChange={e => onChange({
|
||||
...data,
|
||||
limit: e.target.checked ? 1024 : null
|
||||
})}
|
||||
className="rounded border-gray-300"
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<label className="ml-2 text-sm font-medium text-gray-700">Custom Memory Limit (bytes)</label>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
value={data.limit !== null && data.limit !== undefined ? data.limit : ''}
|
||||
onChange={e => onChange({
|
||||
...data,
|
||||
limit: e.target.value ? parseInt(e.target.value) : null
|
||||
})}
|
||||
className="w-full p-2 border rounded text-sm disabled:bg-gray-100"
|
||||
min="0"
|
||||
disabled={isLoading || data.limit === null || data.limit === undefined}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Standard Output</label>
|
||||
<textarea
|
||||
value={data.stdout || ''}
|
||||
onChange={e => onChange({ ...data, stdout: e.target.value })}
|
||||
className="w-full p-2 border rounded font-mono text-sm resize-vertical"
|
||||
rows={3}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Standard Error</label>
|
||||
<textarea
|
||||
value={data.stderr || ''}
|
||||
onChange={e => onChange({ ...data, stderr: e.target.value })}
|
||||
className="w-full p-2 border rounded font-mono text-sm resize-vertical"
|
||||
rows={3}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div className="flex items-center mb-2">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={data.exit_code !== null && data.exit_code !== undefined}
|
||||
onChange={e => onChange({
|
||||
...data,
|
||||
exit_code: e.target.checked ? 0 : null
|
||||
})}
|
||||
className="rounded border-gray-300"
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<label className="ml-2 text-sm font-medium text-gray-700">Exit Code</label>
|
||||
</div>
|
||||
<input
|
||||
type="number"
|
||||
value={data.exit_code !== null && data.exit_code !== undefined ? data.exit_code : ''}
|
||||
onChange={e => onChange({ ...data, exit_code: e.target.value ? parseInt(e.target.value) : null })}
|
||||
className="w-full p-2 border rounded text-sm disabled:bg-gray-100"
|
||||
disabled={isLoading || data.exit_code === null || data.exit_code === undefined}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="flex items-center">
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={data.timed_out || false}
|
||||
onChange={e => onChange({ ...data, timed_out: e.target.checked })}
|
||||
className="rounded border-gray-300"
|
||||
disabled={isLoading}
|
||||
/>
|
||||
<span className="ml-2 text-sm text-gray-700">Timed Out</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<BaseEntry
|
||||
entry={entry}
|
||||
onDelete={onDelete}
|
||||
onUpdate={onUpdate}
|
||||
onReset={onReset}
|
||||
onSave={onSave}
|
||||
renderContent={renderContent}
|
||||
renderEditForm={renderEditForm}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default RepeatEntry;
|
||||
Reference in New Issue
Block a user