New web interface, move llm engine to separate process

This commit is contained in:
2025-05-20 09:43:17 +02:00
parent 895a533e01
commit d4a4902b94
137 changed files with 4850 additions and 3503 deletions

254
web/src/services/api.ts Normal file
View File

@@ -0,0 +1,254 @@
import { AutoApproverConfig } from '../types';
import {
EntryData,
ReasoningEntryData,
ScriptEntryData,
IOEntryData,
ParseErrorEntryData,
} from '../types/entries';
const API_BASE = '/api';
const generateId = (): string => {
const now = new Date();
const utc = new Date(now.getTime() + now.getTimezoneOffset() * 60000);
return utc.getFullYear() +
String(utc.getMonth() + 1).padStart(2, '0') +
String(utc.getDate()).padStart(2, '0') + '_' +
String(utc.getHours()).padStart(2, '0') +
String(utc.getMinutes()).padStart(2, '0') +
String(utc.getSeconds()).padStart(2, '0') + '_' +
String(utc.getMilliseconds()).padStart(3, '0');
};
export const EntryTypes = {
BACKGROUND: 'background',
PARSE_ERROR: 'parse_error',
READ_STDIN: 'read_stdin',
REASONING: 'reasoning',
REPEAT: 'repeat',
SINGLE: 'single',
WRITE: 'write'
} as const;
export type EntryTypeValue = typeof EntryTypes[keyof typeof EntryTypes];
export const getInitialEntryData = (type: EntryTypeValue): Partial<EntryData> => {
const baseEntry = {
type,
id: generateId()
};
switch (type) {
case EntryTypes.BACKGROUND:
case EntryTypes.REPEAT:
case EntryTypes.SINGLE:
return {
...baseEntry,
script: '',
} as Partial<ScriptEntryData>;
case EntryTypes.PARSE_ERROR:
return {
...baseEntry,
content: '',
error: ''
} as Partial<ParseErrorEntryData>;
case EntryTypes.READ_STDIN:
return {
...baseEntry,
} as Partial<IOEntryData>;
case EntryTypes.REASONING:
return {
...baseEntry,
content: ''
} as Partial<ReasoningEntryData>;
case EntryTypes.WRITE:
return {
...baseEntry,
content: '',
} as Partial<IOEntryData>;
default:
return baseEntry;
}
};
interface LLMResponse {
name: string;
}
interface ActiveLLMResponse {
active_llm: string;
}
interface ResponseData {
response: string;
}
interface MemoryResponse {
entries: EntryData[];
}
export const api = {
// LLMs
getLLMs: async (): Promise<LLMResponse[]> => {
const response = await fetch(`${API_BASE}/llms`);
if (!response.ok) throw new Error('Failed to get LLMs');
return response.json();
},
getActiveLLM: async (): Promise<ActiveLLMResponse> => {
const response = await fetch(`${API_BASE}/llms/active`);
if (!response.ok) throw new Error('Failed to get active LLM');
return response.json();
},
setActiveLLM: async (llm: string): Promise<void> => {
const response = await fetch(`${API_BASE}/llms/active`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ active_llm: llm })
});
if (!response.ok) throw new Error('Failed to set active LLM');
},
startInference: async (): Promise<Response> => {
const response = await fetch(`${API_BASE}/inference`, { method: 'POST' });
if (!response.ok) throw new Error('Failed to start inference');
return response;
},
stopInference: async (): Promise<Response> => {
const response = await fetch(`${API_BASE}/inference/stop`, { method: 'POST' });
if (!response.ok) throw new Error('Failed to stop inference');
return response;
},
getResponse: async (): Promise<ResponseData> => {
const response = await fetch(`${API_BASE}/response`);
if (!response.ok) throw new Error('Failed to get response');
return response.json();
},
setResponse: async (responseText: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/response`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ response: responseText })
});
if (!response.ok) throw new Error('Failed to set response');
return response;
},
approveResponse: async (): Promise<Response> => {
const response = await fetch(`${API_BASE}/response/approve`, { method: 'POST' });
if (!response.ok) throw new Error('Failed to approve response');
return response;
},
setAutoApproverConfig: async (config: Partial<AutoApproverConfig>): Promise<Response> => {
const response = await fetch(`${API_BASE}/auto_approver`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(config)
});
if (!response.ok) throw new Error('Failed to set auto approver config');
return response;
},
getMemory: async (): Promise<MemoryResponse> => {
const response = await fetch(`${API_BASE}/memory`);
if (!response.ok) throw new Error('Failed to get memory');
return response.json();
},
createMemoryEntry: async (entryData: Partial<EntryData>): Promise<EntryData> => {
const data = {
...getInitialEntryData(entryData.type as EntryTypeValue),
...entryData
};
const response = await fetch(`${API_BASE}/memory/entry`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) {
const errorText = await response.text();
console.error('Server response:', errorText);
throw new Error('Failed to create entry');
}
return response.json();
},
loadIteration: async (content: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/memory/load_iteration`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ content })
});
if (!response.ok) throw new Error('Failed to load iteration');
return response;
},
deleteMemoryEntry: async (id: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/memory/entry/${id}`, {
method: 'DELETE'
});
if (!response.ok) throw new Error(`Failed to delete entry ${id}`);
return response;
},
updateMemoryEntry: async (id: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/memory/entry/${id}/update`, {
method: 'POST'
});
if (!response.ok) throw new Error(`Failed to update entry ${id}`);
return response;
},
saveMemoryEntry: async <T extends EntryData>(id: string, data: T): Promise<Response> => {
const response = await fetch(`${API_BASE}/memory/entry/${id}`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error(`Failed to save entry ${id}`);
return response;
},
resetMemoryEntry: async (id: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/memory/entry/${id}/reset`, {
method: 'POST'
});
if (!response.ok) throw new Error(`Failed to reset entry ${id}`);
return response;
},
addChatMessage: async (data: { message: string }): Promise<Response> => {
const response = await fetch(`${API_BASE}/chat/message`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
});
if (!response.ok) throw new Error('Failed to add chat message');
return response;
},
deleteChatMessage: async (id: string): Promise<Response> => {
const response = await fetch(`${API_BASE}/chat/message/${id}`, {
method: 'DELETE'
});
if (!response.ok) throw new Error(`Failed to delete chat message ${id}`);
return response;
},
clearChat: async (): Promise<Response> => {
const response = await fetch(`${API_BASE}/chat`, {
method: 'DELETE'
});
if (!response.ok) throw new Error('Failed to clear chat');
return response;
}
};