Added clarity to agents, fixed pinia store reset, modified chunk name paths, fixed invite page and routing

This commit is contained in:
Viswamedha Nalabotu 2026-03-22 15:44:13 +00:00
parent 7bad133150
commit fd9bc9db18
9 changed files with 59 additions and 49 deletions

View file

@ -124,9 +124,9 @@ export const API = {
byId: (uuid: string) => `training-file/${uuid}/`,
retry: (uuid: string) => `training-file/${uuid}/retry/`,
},
roleRagDocuments: {
list: () => 'role-rag-document/',
byId: (uuid: string) => `role-rag-document/${uuid}/`,
knowledgeChunks: {
list: () => 'knowledge-chunk/',
byId: (uuid: string) => `knowledge-chunk/${uuid}/`,
},
},

View file

@ -54,7 +54,7 @@ const router = createRouter({
path: '/invite/:inviteUuid',
name: 'invite-accept',
component: () => import('../views/InviteAccept.vue'),
meta: { requiresAuth: true },
meta: { requiresAuth: true, authRedirect: '/register' },
},
{
path: '/agents',
@ -103,7 +103,8 @@ router.beforeEach((to, from, next) => {
return next({ path: '/' })
}
if (to.meta?.requiresAuth && !isAuthenticated) {
return next({ path: '/login', query: { redirect: to.fullPath } })
const authPath = (to.meta?.authRedirect as string) || '/login'
return next({ path: authPath, query: { redirect: to.fullPath } })
}
if (to.meta?.requiresManager && !isManager) {
return next({ path: '/' })

View file

@ -123,6 +123,9 @@ export const useAgentStore = defineStore('agent', () => {
clearReconnectTimer()
reconnectAttempts = 0
streamBuffer.value = ''
eventLog.value = []
executionStatus.value = 'idle'
lastExecutionId.value = null
if (socket.value) {
socket.value.close()

View file

@ -124,6 +124,10 @@ export const useOnboardingAgentStore = defineStore('onboarding-agent', () => {
intentionalClose = false
clearReconnectTimer()
reconnectAttempts = 0
eventLog.value = []
executionStatus.value = 'idle'
lastExecutionId.value = null
currentPhase.value = null
if (socket.value) {
socket.value.close()

View file

@ -2,6 +2,7 @@
import { ref, onMounted, onUnmounted, computed } from 'vue'
import { useRoute } from 'vue-router'
import {
Alert,
Card,
Typography,
Button,
@ -48,6 +49,13 @@ const agentTypeOptions = [
{ label: 'Assessment Agent', value: 'assessment' },
{ label: 'Progress Monitor', value: 'monitor' },
]
const agentTypeDescriptions: Record<string, string> = {
curriculum: 'Guides new hires through a structured onboarding path — presenting content, tasks, and milestones in a defined sequence for a given role.',
knowledge: 'Answers ad-hoc questions by searching your uploaded training documents and knowledge base. Use this for open-ended Q&A during onboarding.',
assessment: 'Tests understanding through role-specific questions and scenarios, then reports results back to the onboarding session so progress can be tracked.',
monitor: 'Tracks overall session progress and surfaces completions or blockers for manager review without directly interacting with the new hire.',
}
const maxTokens = ref<number>(256)
const queryInput = ref('')
@ -202,6 +210,13 @@ onUnmounted(() => {
disabled
style="width: 100%"
/>
<Alert
v-if="agentTypeDescriptions[agentForm.agent_type]"
:message="agentTypeDescriptions[agentForm.agent_type]"
type="info"
show-icon
style="margin-top: 6px"
/>
</div>
<div>

View file

@ -1,6 +1,6 @@
<script setup lang="ts">
import { ref, onMounted, computed } from 'vue'
import { List, Typography, Button, Card, Spin, message, Tag, Space, Select } from 'ant-design-vue'
import { List, Typography, Button, Card, Spin, message, Tag, Space, Select, Tooltip } from 'ant-design-vue'
import { apiClient, API } from '../router/api'
import type { MaybePaginated } from '../types/common'
import type { AgentConfig } from '../types/agent'
@ -28,6 +28,13 @@ const fetchAgents = async () => {
}
}
const agentTypeDescriptions: Record<string, string> = {
curriculum: 'Guides new hires through a structured onboarding path in sequence.',
knowledge: 'Answers ad-hoc questions by searching uploaded training documents.',
assessment: 'Tests understanding through role-specific questions and reports results.',
monitor: 'Tracks session progress and surfaces completions or blockers.',
}
const getAgentTypeLabel = (type: string) => {
const types: Record<string, string> = {
curriculum: 'Curriculum Agent',
@ -120,9 +127,11 @@ onMounted(() => {
<template #description>
<Space direction="vertical">
<Tag color="geekblue">{{ getRoleLabel(item) }}</Tag>
<Tag color="blue">
{{ getAgentTypeLabel(item.agent_type) }}
</Tag>
<Tooltip :title="agentTypeDescriptions[item.agent_type]">
<Tag color="blue">
{{ getAgentTypeLabel(item.agent_type) }}
</Tag>
</Tooltip>
<span class="config-summary">
Model: {{ item.llm_config?.model_id || 'Default' }}
</span>

View file

@ -109,14 +109,14 @@ const logos = [
<Divider />
<Row :gutter="16">
<Col v-for="stat in stats" :key="stat.title" :xs="24" :sm="8">
<Card :bordered="false" class="stat-card" hoverable>
<Card :bordered="false" class="stat-card">
<Statistic :title="stat.title" :value="stat.value" />
</Card>
</Col>
</Row>
</Col>
<Col :xs="24" :md="10">
<Card class="hero-card" hoverable :cover="null">
<Card class="hero-card" :cover="null">
<img :src="heroImage" alt="Team collaborating" class="hero-img" />
<div class="hero-overlay">Adaptive AI playbooks</div>
</Card>
@ -135,7 +135,7 @@ const logos = [
<Typography.Title :level="2">Everything you need to ramp faster</Typography.Title>
<Row :gutter="16">
<Col v-for="feature in features" :key="feature.title" :xs="24" :md="8">
<Card hoverable class="feature-card">
<Card class="feature-card">
<feature.icon two-tone-color="#2563eb" style="font-size: 28px" />
<Typography.Title :level="4">{{ feature.title }}</Typography.Title>
<Typography.Paragraph>{{ feature.description }}</Typography.Paragraph>
@ -149,7 +149,7 @@ const logos = [
<Typography.Title :level="2">Prebuilt journeys, tailored in minutes</Typography.Title>
<Row :gutter="16">
<Col v-for="journey in journeys" :key="journey.name" :xs="24" :md="8">
<Card hoverable class="journey-card">
<Card class="journey-card">
<template #cover>
<img :alt="journey.name" :src="journey.image" />
</template>

View file

@ -1,22 +1,18 @@
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { Card, Button, Spin, message, Result } from 'ant-design-vue'
import { apiClient, isAxiosError, API } from '../router/api'
import { Card, Spin, message, Result } from 'ant-design-vue'
import { apiClient, API } from '../router/api'
const route = useRoute()
const router = useRouter()
const inviteUuid = route.params.inviteUuid as string
const loading = ref(false)
const accepting = ref(false)
const accepting = ref(true)
const accepted = ref(false)
const error = ref<string | null>(null)
const joinedOrganizationUuid = ref<string | null>(null)
const acceptInvite = async () => {
accepting.value = true
error.value = null
try {
const response = await apiClient.post<{ message?: string; organization?: { uuid?: string } }>(
API.invites.join(inviteUuid),
@ -25,19 +21,10 @@ const acceptInvite = async () => {
message.success(response.data?.message || 'Successfully joined organization')
accepted.value = true
setTimeout(() => {
if (joinedOrganizationUuid.value) {
router.push(`/organization/${joinedOrganizationUuid.value}`)
}
else router.push('/')
router.push(joinedOrganizationUuid.value ? `/organization/${joinedOrganizationUuid.value}` : '/')
}, 1500)
} catch (err) {
console.error('Failed to accept invite:', err)
if (isAxiosError(err)) {
const respErr = err.response?.data?.error || err.response?.data?.detail
error.value = respErr ? String(respErr) : 'Failed to accept invite'
} else {
error.value = 'Failed to accept invite'
}
} catch {
router.push('/')
} finally {
accepting.value = false
}
@ -50,23 +37,14 @@ onMounted(() => {
<template>
<div class="page">
<Spin :spinning="loading" tip="Loading invite...">
<Spin :spinning="accepting" tip="Accepting invite...">
<Card class="panel" :bordered="false">
<div v-if="error">
<Result status="error" :title="error">
<template #extra>
<Button type="primary" @click="router.push('/')">Go Home</Button>
</template>
</Result>
</div>
<div v-else-if="accepted">
<Result
status="success"
title="Successfully Joined Organization"
sub-title="Redirecting to organization page..."
/>
</div>
<Result
v-if="accepted"
status="success"
title="Successfully Joined Organization"
sub-title="Redirecting to organization page..."
/>
</Card>
</Spin>
</div>

View file

@ -936,7 +936,7 @@ onMounted(async () => {
size="small"
/>
<Typography.Paragraph v-else type="secondary">
No training files uploaded yet.
No training files uploaded yet. Use the Upload Training File button to add files you can scope them to a specific role or make them available to all roles.
</Typography.Paragraph>
</div>
</Tabs.TabPane>