feat(app): chat context

This commit is contained in:
dextmorgn
2026-02-09 21:37:56 +01:00
parent 137d16e1fc
commit 19ee40c46d
4 changed files with 55 additions and 16 deletions

View File

@@ -1,16 +1,17 @@
from fastapi import APIRouter, HTTPException, Depends, status
from fastapi.responses import StreamingResponse
from pydantic import BaseModel
from uuid import UUID
from typing import Dict, List, Optional
from uuid import UUID
from fastapi import APIRouter, Depends, HTTPException, status
from fastapi.responses import StreamingResponse
from flowsint_core.core.models import Profile
from flowsint_core.core.postgre_db import get_db
from flowsint_core.core.services import (
NotFoundError,
create_chat_service,
)
from pydantic import BaseModel
from sqlalchemy.orm import Session
from flowsint_core.core.postgre_db import get_db
from flowsint_core.core.models import Profile
from flowsint_core.core.services import (
create_chat_service,
NotFoundError,
)
from app.api.deps import get_current_user
from app.api.schemas.chat import ChatCreate, ChatRead
@@ -19,7 +20,7 @@ router = APIRouter()
class ChatRequest(BaseModel):
prompt: str
context: Optional[List[Dict]] = None
context: Optional[List[str]] = None
@router.get("/", response_model=List[ChatRead])

View File

@@ -13,7 +13,10 @@ interface ChatPanelProps {
}
const formatContext = (context: ChatContextFormat[]): string[] => {
return context.map((item) => `${item.fromLabel} -> ${item.label} -> ${item.toLabel}`)
return context.map((item) => {
if (item.type === 'relation') return `${item.fromLabel} -> ${item.label} -> ${item.toLabel}`
return item.nodeLabel
})
}
export const ChatPanel = ({ onSend, isLoading }: ChatPanelProps) => {
@@ -123,8 +126,22 @@ export const ContextList = memo(({ context }: { context: ChatContextFormat[] })
return (
<div className="flex flex-nowrap overflow-x-auto hide-scrollbar gap-1.5 items-center px-1">
{context.map((item: ChatContextFormat, index: number) => {
const fromColor = item.fromColor ?? colors[item?.fromType]
const toColor = item.toColor ?? colors[item?.toType]
if (item.type === 'node') {
const color = item.nodeColor ?? colors[item.nodeType]
return (
<Badge
key={index}
variant="secondary"
className="flex items-center border border-border gap-1.5 text-xs"
>
<span style={{ background: color }} className="w-1.5 h-1.5 rounded-full" />
{item.nodeLabel || 'Unknown'}
</Badge>
)
}
const fromColor = item.fromColor ?? colors[item.fromType]
const toColor = item.toColor ?? colors[item.toType]
return (
<Badge

View File

@@ -446,8 +446,9 @@ export const useGraphStore = create<GraphState>()(
edgesMapping.forEach((edge) => {
const fromNode = selectedNodesMapping.get(edge.source)
const toNode = selectedNodesMapping.get(edge.target)
if (fromNode && toNode)
if (fromNode && toNode) {
context.push({
type: 'relation',
fromLabel: fromNode.nodeLabel,
fromType: fromNode.nodeType,
fromColor: fromNode.nodeColor,
@@ -456,7 +457,18 @@ export const useGraphStore = create<GraphState>()(
toColor: toNode.nodeColor,
label: edge.label
})
selectedNodesMapping.delete(edge.source)
selectedNodesMapping.delete(edge.target)
}
})
selectedNodesMapping.forEach((node) =>
context.push({
type: 'node',
nodeType: node.nodeType,
nodeLabel: node.nodeLabel,
nodeColor: node?.nodeColor
})
)
return context
},

View File

@@ -9,7 +9,10 @@ export interface ChatMessage {
chatId?: string
}
export type ChatContextFormat = {
export type ChatContextFormat = ChatContextFormatRel | ChatContextFormatNode
export type ChatContextFormatRel = {
type: 'relation'
fromType: string
fromLabel: string
fromColor: string | null
@@ -18,6 +21,12 @@ export type ChatContextFormat = {
toColor: string | null
label: string
}
export type ChatContextFormatNode = {
type: 'node'
nodeLabel: string
nodeColor: string | null
nodeType: string
}
export interface Chat {
id: string