chore(frontend): reduce redundancies
This commit is contained in:
1 parent
dac5d201cd
commit
75dac1e459
8 files changed
+65
-97
No files matched your search
@@ -157,6 +157,14 @@ export function sendAction(action, body = {}, callback = null) {
|
|||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function act (action, body, { alert = null, cache = null } = {}) {
|
||||||
|
const res = await sendAction(action, body);
|
||||||
|
if (res.error) { ui.alert(`Error: ${res.error}`); return null; }
|
||||||
|
if (cache) invalidateCache(cache);
|
||||||
|
if (alert) ui.alert(alert);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
export function ping() {
|
export function ping() {
|
||||||
if (socket && socket.readyState === WebSocket.OPEN) {
|
if (socket && socket.readyState === WebSocket.OPEN) {
|
||||||
const data = JSON.stringify({ path: 'ping' });
|
const data = JSON.stringify({ path: 'ping' });
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// Global utility functions related with UI functionality
|
// Global utility functions related with UI functionality
|
||||||
|
|
||||||
|
import { ref } from 'vue';
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|
||||||
export function goto (path) {
|
export function goto (path) {
|
||||||
@@ -33,6 +34,15 @@ export function contextMenu (entries) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper object to manage track toggable ui elements
|
||||||
|
export function useToggleSet () {
|
||||||
|
const state = ref({});
|
||||||
|
return {
|
||||||
|
has(key) { return Boolean(state.value[key]); },
|
||||||
|
toggle(key) { state.value[key] = !state.value[key]; },
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// === Events === //
|
// === Events === //
|
||||||
|
|
||||||
|
|||||||
@@ -148,45 +148,35 @@
|
|||||||
|
|
||||||
// === Configuration === //
|
// === Configuration === //
|
||||||
|
|
||||||
function updateIdentifier() {
|
async function updateIdentifier() {
|
||||||
const value = prompt(`Enter a new identifier for ${agent.value.name}`);
|
const value = prompt(`Enter a new identifier for ${agent.value.name}`);
|
||||||
if (value) {
|
if (value) {
|
||||||
backend.sendAction("update-agent", {
|
let res = await backend.act("update-agent", {
|
||||||
// agentId is necessary here
|
// agentId is necessary here
|
||||||
agentId: agent.value.id,
|
agentId: agent.value.id,
|
||||||
// used as value instead of identifier
|
// used as value instead of identifier
|
||||||
agentname: value,
|
agentname: value,
|
||||||
}).then(res => {
|
}, {
|
||||||
ui.alert(res.error ?
|
cache: {agents: true},
|
||||||
'Error updating agent identifier' :
|
alert: 'Agent identifier updated'
|
||||||
'Agent identifier updated'
|
|
||||||
);
|
|
||||||
if (!res.error) {
|
|
||||||
agent.value.agentname = value;
|
|
||||||
backend.invalidateCache({agents: true});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
if (!res.error) agent.value.agentname = value;
|
||||||
} else {
|
} else {
|
||||||
ui.alert("Cancelled identifier update");
|
ui.alert("Cancelled identifier update");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateName() {
|
async function updateName() {
|
||||||
const value = prompt(`Enter a new name for ${agent.value.name}`);
|
const value = prompt(`Enter a new name for ${agent.value.name}`);
|
||||||
if (value) {
|
if (value) {
|
||||||
backend.sendAction("update-agent", {
|
let res = await backend.sendAction("update-agent", {
|
||||||
agentname: agent.value.agentname,
|
agentname: agent.value.agentname,
|
||||||
name: value,
|
name: value,
|
||||||
}).then(res => {
|
}, {
|
||||||
ui.alert(res.error ?
|
alert: 'Agent name updated',
|
||||||
'Error updating agent name' :
|
cache: {agents: true},
|
||||||
'Agent name updated'
|
|
||||||
);
|
|
||||||
if (!res.error) {
|
|
||||||
agent.value.name = value;
|
|
||||||
backend.invalidateCache({agents: true});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
if (!res.error) agent.value.name = value;
|
||||||
} else {
|
} else {
|
||||||
ui.alert("Cancelled name update");
|
ui.alert("Cancelled name update");
|
||||||
}
|
}
|
||||||
@@ -215,19 +205,13 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let res = await backend.sendAction("update-agent", {
|
await backend.act("update-agent", {
|
||||||
agentname: agent.value.agentname,
|
agentname: agent.value.agentname,
|
||||||
data: dataObject,
|
data: dataObject,
|
||||||
|
}, {
|
||||||
|
alert: 'Agent updated',
|
||||||
|
cache: {agents: true},
|
||||||
});
|
});
|
||||||
|
|
||||||
ui.alert(res.error ?
|
|
||||||
'Error updating agent' :
|
|
||||||
'Agent updated'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!res.error) {
|
|
||||||
backend.invalidateCache({agents: true});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function saveAddingTool() {
|
async function saveAddingTool() {
|
||||||
@@ -292,8 +276,8 @@
|
|||||||
<span class="label">Enable Instruction/Input</span>
|
<span class="label">Enable Instruction/Input</span>
|
||||||
<input type="checkbox" v-model="promptInstructionEnabled" />
|
<input type="checkbox" v-model="promptInstructionEnabled" />
|
||||||
</div>
|
</div>
|
||||||
<textarea v-if="promptInstructionEnabled" v-model="promptInstruction" class="config-input" @keydown="promptKeyDown($event, 1)" />
|
<textarea v-if="promptInstructionEnabled" v-model="promptInstruction" class="config-input" @keydown.ctrl.enter.prevent="promptInputElem.focus" />
|
||||||
<textarea v-model="promptInput" class="config-input" ref="promptInputElem" @keydown="promptKeyDown($event, 2)" />
|
<textarea v-model="promptInput" class="config-input" ref="promptInputElem" @keydown.ctrl.enter.prevent="sendPrompt" />
|
||||||
<div>
|
<div>
|
||||||
<button @click="sendPrompt()">Send Prompt</button>
|
<button @click="sendPrompt()">Send Prompt</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -39,14 +39,13 @@
|
|||||||
payload.temporary = true;
|
payload.temporary = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await backend.sendAction("create-agent", payload);
|
let response = await backend.act("create-agent", payload, {
|
||||||
|
alert: `Created Agent "${payload.name}"`,
|
||||||
|
cache: {agents: true},
|
||||||
|
});
|
||||||
|
|
||||||
if (response.error) {
|
if (!response.error) {
|
||||||
ui.alert(`Could not create agent\n${response.error}`);
|
|
||||||
} else {
|
|
||||||
ui.alert(`Created Agent "${payload.name}"`);
|
|
||||||
backend.invalidateCache({agents: true});
|
backend.invalidateCache({agents: true});
|
||||||
ui.goto(`/agent/${payload.agentname}`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,9 @@
|
|||||||
} = session;
|
} = session;
|
||||||
|
|
||||||
// UI state coupled to the document itself
|
// UI state coupled to the document itself
|
||||||
const expandedLogs = ref({}); // Message ids of logs currently expanded
|
|
||||||
|
// Message ids of logs currently expanded
|
||||||
|
const expandedLogs = ui.useToggleSet();
|
||||||
const inputFieldElem = ref(null);
|
const inputFieldElem = ref(null);
|
||||||
const chatContainerElem = ref(null);
|
const chatContainerElem = ref(null);
|
||||||
|
|
||||||
@@ -109,10 +111,6 @@
|
|||||||
|
|
||||||
// === UI Helper Functions === //
|
// === UI Helper Functions === //
|
||||||
|
|
||||||
function toggleLogExpand (message) {
|
|
||||||
expandedLogs.value[message.id] = !expandedLogs.value[message.id];
|
|
||||||
}
|
|
||||||
|
|
||||||
async function chatEntryContextMenu (message, logMeta) {
|
async function chatEntryContextMenu (message, logMeta) {
|
||||||
let entries = [
|
let entries = [
|
||||||
{value: 'pin', title: "Pin message"},
|
{value: 'pin', title: "Pin message"},
|
||||||
@@ -143,7 +141,7 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'toggle-log': {
|
case 'toggle-log': {
|
||||||
toggleLogExpand(message);
|
expandedLogs.toggle(message.id);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'delete': {
|
case 'delete': {
|
||||||
@@ -178,13 +176,6 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function inputKeyDown (event) {
|
|
||||||
if (event.key == "Enter" && event.ctrlKey) {
|
|
||||||
event.preventDefault();
|
|
||||||
sendMessage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -203,10 +194,10 @@
|
|||||||
:key="msg.id ?? ('thread-' + msg.threadId)"
|
:key="msg.id ?? ('thread-' + msg.threadId)"
|
||||||
:message="msg"
|
:message="msg"
|
||||||
@open-menu="chatEntryContextMenu"
|
@open-menu="chatEntryContextMenu"
|
||||||
@open-thread="session.activateThread"
|
@open-thread="session.activateThread($event)"
|
||||||
|
|
||||||
:log-expanded="expandedLogs[msg.id]"
|
:log-expanded="expandedLogs.has(msg.id)"
|
||||||
@toggle-log="toggleLogExpand(msg)"
|
@toggle-log="expandedLogs.toggle(msg.id)"
|
||||||
|
|
||||||
:cancellable="messageRunMap[msg.id]"
|
:cancellable="messageRunMap[msg.id]"
|
||||||
@cancel="session.cancelMessageRun(msg.id)"
|
@cancel="session.cancelMessageRun(msg.id)"
|
||||||
@@ -218,7 +209,7 @@
|
|||||||
{{editInfo}}
|
{{editInfo}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-field" ref="inputFieldElem" @keydown="inputKeyDown($event)" contenteditable></div>
|
<div class="input-field" ref="inputFieldElem" @keydown.ctrl.enter.prevent="sendMessage" contenteditable></div>
|
||||||
|
|
||||||
<div class="input-row">
|
<div class="input-row">
|
||||||
<button @click="session.startNewThread()">
|
<button @click="session.startNewThread()">
|
||||||
|
|||||||
@@ -25,13 +25,14 @@
|
|||||||
payload.temporary = true;
|
payload.temporary = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
let response = await backend.sendAction("create-chat", payload);
|
let response = await backend.act("create-chat", payload, {
|
||||||
|
alert: `Created Chat "${title.value}"`,
|
||||||
|
cache: {chats: true},
|
||||||
|
});
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
ui.alert(`Could not create chat\n${response.error}`);
|
ui.alert(`Could not create chat\n${response.error}`);
|
||||||
} else {
|
} else {
|
||||||
ui.alert(`Created Chat "${title.value}"`);
|
|
||||||
backend.invalidateCache({chats: true});
|
|
||||||
ui.goto(`/chat/${response.chatId}`);
|
ui.goto(`/chat/${response.chatId}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
import * as ui from '../ui';
|
import * as ui from '../ui';
|
||||||
|
|
||||||
const models = ref([]);
|
const models = ref([]);
|
||||||
const expandedModelId = ref(new Set());
|
const expandedModelId = ui.useToggleSet();
|
||||||
const createExpanded = ref(false);
|
const createExpanded = ref(false);
|
||||||
const newKeyValue = ref(false);
|
const newKeyValue = ref(false);
|
||||||
|
|
||||||
@@ -22,14 +22,6 @@
|
|||||||
models.value = res.models.map(entry => ({editing: {}, ...entry}));
|
models.value = res.models.map(entry => ({editing: {}, ...entry}));
|
||||||
});
|
});
|
||||||
|
|
||||||
const toggleModel = (id) => {
|
|
||||||
if (expandedModelId.value.has(id)) {
|
|
||||||
expandedModelId.value.delete(id);
|
|
||||||
} else {
|
|
||||||
expandedModelId.value.add(id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
async function createModel () {
|
async function createModel () {
|
||||||
let current = Object.assign({editing: {}}, editModel.value);
|
let current = Object.assign({editing: {}}, editModel.value);
|
||||||
|
|
||||||
@@ -114,7 +106,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else v-for="model in models" :key="model.id" class="model-entry">
|
<div v-else v-for="model in models" :key="model.id" class="model-entry">
|
||||||
<div class="model-header" @click="toggleModel(model.id)">
|
<div class="model-header" @click="expandedModelId.toggle(model.id)">
|
||||||
<span class="model-name">{{ model.name }}</span>
|
<span class="model-name">{{ model.name }}</span>
|
||||||
<span class="model-kind">{{ model.kind }}</span>
|
<span class="model-kind">{{ model.kind }}</span>
|
||||||
<div class="model-actions">
|
<div class="model-actions">
|
||||||
|
|||||||
@@ -108,10 +108,10 @@ import * as ui from '../ui';
|
|||||||
const upstreamRemotes = ref([]);
|
const upstreamRemotes = ref([]);
|
||||||
|
|
||||||
/** Expanded remote rows, keyed by row key; several can be open at once */
|
/** Expanded remote rows, keyed by row key; several can be open at once */
|
||||||
const expandedRemotes = ref(new Set());
|
const expandedRemotes = ui.useToggleSet();
|
||||||
|
|
||||||
/** Expanded function rows, keyed by `<rowKey>|<fnKey>` */
|
/** Expanded function rows, keyed by `<rowKey>|<fnKey>` */
|
||||||
const expandedFns = ref(new Set());
|
const expandedFns = ui.useToggleSet();
|
||||||
|
|
||||||
/** Per-function call state, keyed like expandedFns */
|
/** Per-function call state, keyed like expandedFns */
|
||||||
const callStates = reactive({});
|
const callStates = reactive({});
|
||||||
@@ -222,27 +222,10 @@ function functionsOf(row) {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Expansion ----
|
// Function key, used in expandedFns
|
||||||
|
|
||||||
function toggleRemote(key) {
|
|
||||||
const set = new Set(expandedRemotes.value);
|
|
||||||
if (set.has(key)) set.delete(key); else set.add(key);
|
|
||||||
expandedRemotes.value = set;
|
|
||||||
}
|
|
||||||
|
|
||||||
function fnKey(row, fn) {
|
function fnKey(row, fn) {
|
||||||
return fn.id != null ? `l${fn.id}` : `u${fn.name}`;
|
let fkey = fn.id != null ? `l${fn.id}` : `u${fn.name}`;
|
||||||
}
|
return `${row.key}|${fkey}`;
|
||||||
|
|
||||||
function fnStateKey(row, fn) {
|
|
||||||
return `${row.key}|${fnKey(row, fn)}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
function toggleFn(row, fn) {
|
|
||||||
const key = fnStateKey(row, fn);
|
|
||||||
const set = new Set(expandedFns.value);
|
|
||||||
if (set.has(key)) set.delete(key); else set.add(key);
|
|
||||||
expandedFns.value = set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---- Calling ----
|
// ---- Calling ----
|
||||||
@@ -276,7 +259,7 @@ function defaultArgs(fn) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function callStateFor(row, fn) {
|
function callStateFor(row, fn) {
|
||||||
const key = fnStateKey(row, fn);
|
const key = fnKey(row, fn);
|
||||||
if (!callStates[key]) {
|
if (!callStates[key]) {
|
||||||
callStates[key] = { args: defaultArgs(fn), result: null, error: '', busy: false };
|
callStates[key] = { args: defaultArgs(fn), result: null, error: '', busy: false };
|
||||||
}
|
}
|
||||||
@@ -413,7 +396,7 @@ function removeArgument(fn, argIdx) {
|
|||||||
<template v-for="row in remoteRows" :key="rowKey(row)">
|
<template v-for="row in remoteRows" :key="rowKey(row)">
|
||||||
<!-- Remote row -->
|
<!-- Remote row -->
|
||||||
<div class="rt-row rt-remote" :class="{ open: expandedRemotes.has(row.key) }">
|
<div class="rt-row rt-remote" :class="{ open: expandedRemotes.has(row.key) }">
|
||||||
<div class="col-arrow toggle" @click="toggleRemote(row.key)">
|
<div class="col-arrow toggle" @click="expandedRemotes.toggle(row.key)">
|
||||||
{{ expandedRemotes.has(row.key) ? '▼' : '▶' }}
|
{{ expandedRemotes.has(row.key) ? '▼' : '▶' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-name">
|
<div class="col-name">
|
||||||
@@ -464,8 +447,8 @@ function removeArgument(fn, argIdx) {
|
|||||||
<template v-for="fn in functionsOf(row)" :key="fnKey(row, fn)">
|
<template v-for="fn in functionsOf(row)" :key="fnKey(row, fn)">
|
||||||
<!-- Function row -->
|
<!-- Function row -->
|
||||||
<div class="rt-row rt-fn">
|
<div class="rt-row rt-fn">
|
||||||
<div class="col-arrow toggle" @click="toggleFn(row, fn)">
|
<div class="col-arrow toggle" @click="expandedFns.toggle(fnKey(row, fn))">
|
||||||
{{ expandedFns.has(fnStateKey(row, fn)) ? '▼' : '▶' }}
|
{{ expandedFns.has(fnKey(row, fn)) ? '▼' : '▶' }}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-name">
|
<div class="col-name">
|
||||||
<input
|
<input
|
||||||
@@ -499,7 +482,7 @@ function removeArgument(fn, argIdx) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Expanded function detail: left = arguments, right = output/body -->
|
<!-- Expanded function detail: left = arguments, right = output/body -->
|
||||||
<div v-if="expandedFns.has(fnStateKey(row, fn))" class="rt-row rt-fndetail">
|
<div v-if="expandedFns.has(fnKey(row, fn))" class="rt-row rt-fndetail">
|
||||||
<div class="col-arrow"></div>
|
<div class="col-arrow"></div>
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
<!-- Callable mode (connected remotes) -->
|
<!-- Callable mode (connected remotes) -->
|
||||||
|
|||||||
Reference in new issue
Block a user