Skip to content

Different thread style #31

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,17 @@
"version": "0.2.0",
"configurations": [
{
"name": "Launch file",
"name": "Launch UI",
"type": "node",
"request": "launch",
"program": "${workspaceFolder}/ui/node_modules/.bin/nuxt",
"args": ["dev"],
"skipFiles": [
"<node_internals>/**"
]
},
{
"name": "Launch Server",
"type": "go",
"request": "launch",
"mode": "debug",
Expand Down
6 changes: 6 additions & 0 deletions ui/app.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,11 @@ export default defineAppConfig({
ui: {
primary: 'slate',
gray: 'cool',

card: {
body: {
padding: 'px-1 py-1 sm:p-2'
}
}
},
})
25 changes: 5 additions & 20 deletions ui/app.vue
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
<script lang="ts" setup>
import '@/styles/app.scss'

const sock = useSocket()
</script>
<template>
<div class="root bg-slate-100 dark:bg-slate-950">
<nav class="bg-slate-200 dark:bg-slate-900">
<LeftNav />
</nav>
<aside class="bg-slate-200 dark:bg-slate-900">
<ThemeToggle />
{{sock.status}}
</aside>
<LeftNav class="left-nav bg-slate-200 dark:bg-slate-900"/>
<main>
<NuxtPage />
</main>
Expand All @@ -21,27 +13,20 @@
<style lang="scss" scoped>
.root {
--nav-width: 300px;
--aside-height: 50px;

display: grid;
grid-template-areas: "nav main"
"aside main";
grid-template-areas: "nav main";
grid-template-columns: var(--nav-width) 1fr;
grid-template-rows: 1fr var(--aside-height);

position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;

NAV {
.left-nav {
grid-area: nav;
overflow: auto;
}

ASIDE {
grid-area: aside;
line-height: var(--aside-height);
max-height: 100vh;
}

MAIN {
Expand Down
4 changes: 2 additions & 2 deletions ui/components/arguments.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ interface Props {

const { schema, modelValue: initialState } = defineProps<Props>()
const form = ref()
const state = reactive(clone(initialState || {}))
const state = reactive<any>(clone(initialState || {}))

if ( schema ) {
for ( const k in schema.properties ) {
Expand Down Expand Up @@ -70,7 +70,7 @@ watchEffect(() => {
</UFormGroup>
</template>
<template v-else>
<UTextarea autoresize :rows="1" :value="state[k]" @update:modelValue="(v) => state[k] = v" />
<UTextarea autoresize :rows="1" :value="state" @update:modelValue="(v) => state = v" />
</template>
</UForm>
</div>
Expand Down
89 changes: 68 additions & 21 deletions ui/components/call.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,28 @@ interface Props {
const { run, call, referredTo, callMap, depth=0 } = defineProps<Props>()
const prefs = usePrefs()

const isExpanded = computed(() => {
return prefs.allExpanded || prefs.expanded[call.id] || false
})

const children = computed(() => {
return run.calls.filter(x => !referredTo[x.id] && x.parentID && x.parentID === call.id)
return run.calls.filter(x => (!isExpanded.value || !call.showSystemMessages || !referredTo[x.id]) && x.parentID && x.parentID === call.id)
})

const isExpanded = computed(() => {
return prefs.allExpanded || prefs.expanded[call.id] || false
const messages = computed(() => {
const all = call.messages || []

if ( call.showSystemMessages ) {
return all.slice()
} else {
return all.filter((msg) => {
if ( ('role' in msg) ) {
return false
}

return true
})
}
})

const icon = computed(() => {
Expand Down Expand Up @@ -54,38 +70,71 @@ const displayName = computed(() => {

return id.replace(/:1$/,'')
})

const inputLimit = 50
const outputLimit = 100
const inputDisplay = computed(() => {
return `${call.input || '<none>'}`
})

const inputShort = computed(() => {
return inputDisplay.value.substring(0, inputLimit) + (inputTruncated.value ? '…' : '')
})

const inputTruncated = computed(() => {
return inputDisplay.value.length > inputLimit
})

const outputDisplay = computed(() => {
return `${call.output || '<none>'}`
})

const outputShort = computed(() => {
return outputDisplay.value.substring(0, outputLimit) + (outputTruncated.value ? '…' : '')
})

const outputTruncated = computed(() => {
return outputDisplay.value.length > outputLimit
})

</script>
<template>
<UCard :key="call.id" class="call">
<UCard :key="call.id" class="call mt-3">
<i v-if="prefs.debug" class="text-blue-400">{{call}}</i>
<div class="clearfix">
<div class="float-left">
<div class="flex" :class="[isExpanded && 'mb-2']">
<div class="flex-1">
<div>
<UButton v-if="children.length || call.messages?.length" size="xs" :icon="icon" @click="toggle" class="align-baseline"/>
<UButton v-if="children.length || call.messages?.length || inputTruncated || outputTruncated" size="xs" :icon="icon" @click="toggle" class="align-baseline mr-1"/>
{{displayName}}
<template v-if="!isExpanded">({{inputShort}}) <i class="i-heroicons-arrow-right align-text-bottom"/> {{outputShort}}</template>
</div>
</div>
<div class="float-right">
<UBadge class="align-baseline mr-2" :id="call.id">
<div class="flex-inline text-right">
<UTooltip v-if="isExpanded" :text="call.showSystemMessages ? 'Internal messages shown' : 'Internal messages hidden'">
<UToggle v-model="call.showSystemMessages" class="mr-2" off-icon="i-heroicons-bars-2" on-icon="i-heroicons-bars-4" />
</UTooltip>

<!-- <UBadge size="md" class="align-baseline mr-2" :id="call.id" variant="subtle">
<i class="i-heroicons-key"/>&nbsp;{{ prefs.mapCall(call.id) }}
</UBadge>
<UBadge :color="colorForState(call.state)" class="align-baseline">
</UBadge> -->
<UBadge size="md" :color="colorForState(call.state)" class="align-baseline" variant="subtle">
<i :class="iconForState(call.state)"/>&nbsp;{{ucFirst(call.state)}}
</UBadge>
</div>
</div>
<div>
<b>Input:</b> {{call.input || '<none>'}}

<div v-if="isExpanded">
<b>Input:</b> <span class="whitespace-pre-wrap">{{call.input || '<none>'}}</span>
</div>
<div>
<b>Output:</b> <span v-html="nlToBr(call.output || '<none>')"/>
<div v-if="isExpanded">
<b>Output:</b> <span class="whitespace-pre-wrap">{{call.output || '<none>'}}</span>
</div>

<template v-if="isExpanded && call.messages?.length">
<template v-if="isExpanded">
<Message
v-for="(msg, idx) in call.messages"
v-for="(msg, idx) in messages"
:key="idx"
class="my-2"
class="mt-1"
:run="run"
:call="call"
:msg="msg"
Expand All @@ -95,9 +144,7 @@ const displayName = computed(() => {
/>
</template>

<div v-if="isExpanded && children.length" class="ml-5">
CHILDREN
{{referredTo}}
<div v-if="children.length" class="ml-9">
<Call
v-for="(child, idx) in children"
:key="idx"
Expand Down
78 changes: 52 additions & 26 deletions ui/components/left-nav.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// const router = useRouter()
const gptList = await useGpts().listAll()
const runList = await useRuns().findAll()
const sock = useSocket()

const gptLinks = computed(() => {
return (gptList || []).map(x => { return {
Expand All @@ -13,12 +14,13 @@ const gptLinks = computed(() => {

const runLinks = computed(() => {
const out = (runList || []).map(x => { return {
label: x.id,
id: x.id,
label: (x.program?.name || '') + ' #' + x.id,
icon: iconForState(x.state), // 'i-heroicons-cog animate-spin', // iconForState(x.state),
to: `/run/${encodeURIComponent(x.id)}`
}})

return sortBy(out, 'label:desc')
return sortBy(out, 'id:desc')
})

async function remove(e: MouseEvent, id: any) {
Expand All @@ -28,37 +30,61 @@ async function remove(e: MouseEvent, id: any) {
</script>

<template>
<div class="mt-5">
<h4>GPTScripts</h4>
<UVerticalNavigation :links="gptLinks" />
<nav class="left">
<div class="scripts text-slate-700 dark:text-slate-400">
<h4 class="header px-3 py-2 bg-slate-300 dark:bg-slate-800">GPTScripts</h4>
<UVerticalNavigation :links="gptLinks" />
</div>

<h4 class="mt-5">
Runs
</h4>
<UVerticalNavigation :links="runLinks">
<template #badge="{ link }">
<UButton
class="absolute right-2 delete-btn"
icon="i-heroicons-trash"
aria-label="Delete"
@click="e => remove(e, link.id)"
size="xs"
/>
</template>
</UVerticalNavigation>
</div>
<div class="runs text-slate-700 dark:text-slate-400">
<h4 class="header px-3 py-2 bg-slate-300 dark:bg-slate-800">Run History</h4>
<UVerticalNavigation :links="runLinks">
<template #badge="{ link }">
<UButton
class="absolute right-2 delete-btn"
icon="i-heroicons-trash"
aria-label="Delete"
@click="e => remove(e, link.id)"
size="xs"
/>
</template>
</UVerticalNavigation>
</div>

<aside class="px-2 flex">
<div class="flex-1 mt-1">
<ThemeToggle />
</div>
<div class="flex-initial text-right" v-if="sock.sock.status !== 'OPEN'">
<UBadge color="red" class="mt-2">
<i class="i-heroicons-bolt-slash"/>&nbsp;{{ucFirst(sock.sock.status.toLowerCase())}}
</UBadge>
</div>
</aside>
</nav>
</template>

<style lang="scss" scoped>
H4 {
padding-left: 1rem;
$aside-height: 45px;

.left {
display: grid;
grid-template-areas: "scripts" "runs" "aside";
grid-template-rows: 1fr 1fr $aside-height;
height: 100%;
}

LI {
display: block;
.scripts {
grid-area: scripts;
overflow-y: auto;
}
.active {
background-color: red;

.runs {
grid-area: runs;
overflow-y: auto;
}

ASIDE {
}

.delete-btn {
Expand Down
10 changes: 5 additions & 5 deletions ui/components/message.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,20 @@ const { run, /*call,*/ msg, referredTo, depth=0 } = defineProps<Props>()
v-else-if="'err' in msg"
icon="i-heroicons-exclamation-triangle"
color="red"
class="my-5"
class="my-2"
title="Error"
variant="solid"
:description="msg.err"
/>
<template v-else>
<UCard v-if="typeof msg.content === 'string'" class="mb-5">
<b>{{ucFirst(msg.role)}}:</b>
{{msg.content}}
<UCard v-if="typeof msg.content === 'string'" class="mt-2">
<b>{{ucFirst(msg.role)}}:&nbsp;</b>
<span class="whitespace-pre-wrap">{{`${msg.content}`.trim()}}</span>
</UCard>
<template v-else>
<UCard v-for="(c, idx) in msg.content" :key="idx">
<template v-if="'text' in c">
<b>{{ucFirst(msg.role)}}:</b>
<b>{{ucFirst(msg.role)}}:&nbsp;</b>
{{c.text}}
</template>
<template v-else>
Expand Down
5 changes: 4 additions & 1 deletion ui/config/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ declare global {
}

interface Gpt {
name: string
entryToolId: string
toolSet: Record<string, Tool>
}
Expand All @@ -35,6 +36,7 @@ declare global {
arguments: ArgSchema
instructions: string
tools: string[]
localTools: Record<string,string>
toolMapping: Record<string,string>
modelName: string
source: {
Expand Down Expand Up @@ -64,6 +66,7 @@ declare global {
chatRequest?: JsonDict
input?: Args
output?: string
showSystemMessages?: boolean
}

interface BaseFrame {
Expand Down Expand Up @@ -145,7 +148,7 @@ declare global {
}

interface ChatToolMessage {
role: "system"|"assistant"|"user"
role: "system"|"assistant"|"user"|"tool"
content: string | (ChatToolCall|ChatText)[]
}

Expand Down
Loading