From fd6ee0d736e04793aec8d6d36e3a4fdff9b49ab8 Mon Sep 17 00:00:00 2001 From: Ivan <8611739+IRBorisov@users.noreply.github.com> Date: Wed, 23 Jul 2025 12:09:01 +0300 Subject: [PATCH] F: Implement schema variables + small UI fixes --- rsconcept/frontend/src/features/ai/labels.ts | 4 +++ .../src/features/ai/models/prompting-api.ts | 36 +++++++++++++++---- .../src/features/ai/models/prompting.ts | 6 ++-- .../src/features/ai/stores/ai-context.ts | 6 ++++ .../ai/stores/use-available-variables.tsx | 16 +++++++-- .../features/help/items/ui/help-rsmenu.tsx | 4 --- .../rsform/pages/rsform-page/menu-main.tsx | 21 +---------- 7 files changed, 58 insertions(+), 35 deletions(-) diff --git a/rsconcept/frontend/src/features/ai/labels.ts b/rsconcept/frontend/src/features/ai/labels.ts index 750d0de9..2654a714 100644 --- a/rsconcept/frontend/src/features/ai/labels.ts +++ b/rsconcept/frontend/src/features/ai/labels.ts @@ -5,6 +5,8 @@ const describePromptVariableRecord: Record = { [PromptVariableType.OSS]: 'Текущая операционная схема', [PromptVariableType.SCHEMA]: 'Текущая концептуальная схема', [PromptVariableType.SCHEMA_THESAURUS]: 'Термины и определения текущей концептуальной схемы', + [PromptVariableType.SCHEMA_GRAPH]: 'Граф связей определений конституент', + [PromptVariableType.SCHEMA_TYPE_GRAPH]: 'Граф ступеней концептуальной схемы', [PromptVariableType.CONSTITUENTA]: 'Текущая конституента', [PromptVariableType.CONSTITUENTA_SYNTAX_TREE]: 'Синтаксическое дерево конституенты' }; @@ -14,6 +16,8 @@ const mockPromptVariableRecord: Record = { [PromptVariableType.OSS]: 'Пример: Текущая операционная схема', [PromptVariableType.SCHEMA]: 'Пример: Текущая концептуальная схема', [PromptVariableType.SCHEMA_THESAURUS]: 'Пример\nТермин1 - Определение1\nТермин2 - Определение2', + [PromptVariableType.SCHEMA_GRAPH]: 'Пример: Граф связей определений конституент', + [PromptVariableType.SCHEMA_TYPE_GRAPH]: 'Пример: Граф ступеней концептуальной схемы', [PromptVariableType.CONSTITUENTA]: 'Пример: Текущая конституента', [PromptVariableType.CONSTITUENTA_SYNTAX_TREE]: 'Пример синтаксического дерева конституенты' }; diff --git a/rsconcept/frontend/src/features/ai/models/prompting-api.ts b/rsconcept/frontend/src/features/ai/models/prompting-api.ts index fa9f2def..792b4d26 100644 --- a/rsconcept/frontend/src/features/ai/models/prompting-api.ts +++ b/rsconcept/frontend/src/features/ai/models/prompting-api.ts @@ -2,6 +2,7 @@ import { type IBlock, type IOperationSchema, NodeType } from '@/features/oss/mod import { CstType, type IConstituenta, type IRSForm } from '@/features/rsform'; import { labelCstTypification } from '@/features/rsform/labels'; import { isBasicConcept } from '@/features/rsform/models/rsform-api'; +import { TypificationGraph } from '@/features/rsform/models/typification-graph'; import { PARAMETER } from '@/utils/constants'; @@ -41,9 +42,9 @@ export function varSchema(schema: IRSForm): string { result += `[${schema.alias}] Описание: "${schema.description}"\n\n`; result += 'Понятия:\n'; schema.items.forEach(item => { - result += `${item.alias} - "${labelCstTypification(item)}" - "${item.term_resolved}" - "${ + result += `\n${item.alias} - "${labelCstTypification(item)}" - "${item.term_resolved}" - "${ item.definition_formal - }" - "${item.definition_resolved}" - "${item.convention}"\n`; + }" - "${item.definition_resolved}" - "${item.convention}"`; }); return result; } @@ -58,14 +59,37 @@ export function varSchemaThesaurus(schema: IRSForm): string { return; } if (isBasicConcept(item.cst_type)) { - result += `${item.term_resolved} - "${item.convention}"\n`; + result += `\n${item.term_resolved} - "${item.convention}"`; } else { - result += `${item.term_resolved} - "${item.definition_resolved}"\n`; + result += `\n${item.term_resolved} - "${item.definition_resolved}"`; } }); return result; } +/** Generates a prompt for a schema graph variable. */ +export function varSchemaGraph(schema: IRSForm): string { + let result = `Название концептуальной схемы: ${schema.title}\n`; + result += `[${schema.alias}] Описание: "${schema.description}"\n\n`; + result += 'Узлы графа\n'; + result += JSON.stringify(schema.items, null, PARAMETER.indentJSON); + result += '\n\nСвязи графа'; + schema.graph.nodes.forEach(node => (result += `\n${node.id} -> ${node.outputs.join(', ')}`)); + return result; +} + +/** Generates a prompt for a schema type graph variable. */ +export function varSchemaTypeGraph(schema: IRSForm): string { + const graph = new TypificationGraph(); + schema.items.forEach(item => graph.addConstituenta(item.alias, item.parse.typification, item.parse.args)); + + let result = `Название концептуальной схемы: ${schema.title}\n`; + result += `[${schema.alias}] Описание: "${schema.description}"\n\n`; + result += 'Ступени\n'; + result += JSON.stringify(graph.nodes, null, PARAMETER.indentJSON); + return result; +} + /** Generates a prompt for a OSS variable. */ export function varOSS(oss: IOperationSchema): string { let result = `Название операционной схемы: ${oss.title}\n`; @@ -86,7 +110,7 @@ export function varOSS(oss: IOperationSchema): string { result += `\nОперация ${operation.id}: ${operation.alias}\n`; result += `Название: ${operation.title}\n`; result += `Описание: ${operation.description}\n`; - result += `Блок: ${operation.parent}\n`; + result += `Блок: ${operation.parent}`; }); return result; } @@ -107,7 +131,7 @@ export function varBlock(target: IBlock, oss: IOperationSchema): string { operations.forEach(operation => { result += `\nОперация ${operation.id}: ${operation.alias}\n`; result += `Название: "${operation.title}"\n`; - result += `Описание: "${operation.description}"\n`; + result += `Описание: "${operation.description}"`; }); return result; } diff --git a/rsconcept/frontend/src/features/ai/models/prompting.ts b/rsconcept/frontend/src/features/ai/models/prompting.ts index 73301fc1..c1725349 100644 --- a/rsconcept/frontend/src/features/ai/models/prompting.ts +++ b/rsconcept/frontend/src/features/ai/models/prompting.ts @@ -2,11 +2,11 @@ export const PromptVariableType = { SCHEMA: 'schema', SCHEMA_THESAURUS: 'schema.thesaurus', - // SCHEMA_GRAPH: 'schema.graph', - // SCHEMA_TYPE_GRAPH: 'schema.type-graph', + SCHEMA_GRAPH: 'schema.graph', + SCHEMA_TYPE_GRAPH: 'schema.type-graph', CONSTITUENTA: 'constituenta', - CONSTITUENTA_SYNTAX_TREE: 'constituent.ast', + CONSTITUENTA_SYNTAX_TREE: 'constituenta.ast', OSS: 'oss', diff --git a/rsconcept/frontend/src/features/ai/stores/ai-context.ts b/rsconcept/frontend/src/features/ai/stores/ai-context.ts index d9538cff..96229dc3 100644 --- a/rsconcept/frontend/src/features/ai/stores/ai-context.ts +++ b/rsconcept/frontend/src/features/ai/stores/ai-context.ts @@ -9,7 +9,9 @@ import { varConstituenta, varOSS, varSchema, + varSchemaGraph, varSchemaThesaurus, + varSchemaTypeGraph, varSyntaxTree } from '../models/prompting-api'; @@ -68,6 +70,10 @@ export function evaluatePromptVariable(variableType: PromptVariableType, context return context.currentSchema ? varSchema(context.currentSchema) : `!${variableType}!`; case PromptVariableType.SCHEMA_THESAURUS: return context.currentSchema ? varSchemaThesaurus(context.currentSchema) : `!${variableType}!`; + case PromptVariableType.SCHEMA_GRAPH: + return context.currentSchema ? varSchemaGraph(context.currentSchema) : `!${variableType}!`; + case PromptVariableType.SCHEMA_TYPE_GRAPH: + return context.currentSchema ? varSchemaTypeGraph(context.currentSchema) : `!${variableType}!`; case PromptVariableType.BLOCK: return context.currentBlock && context.currentOSS ? varBlock(context.currentBlock, context.currentOSS) diff --git a/rsconcept/frontend/src/features/ai/stores/use-available-variables.tsx b/rsconcept/frontend/src/features/ai/stores/use-available-variables.tsx index e04b6a8d..7dbe2b91 100644 --- a/rsconcept/frontend/src/features/ai/stores/use-available-variables.tsx +++ b/rsconcept/frontend/src/features/ai/stores/use-available-variables.tsx @@ -10,8 +10,20 @@ export function useAvailableVariables(): PromptVariableType[] { return [ ...(hasCurrentOSS ? [PromptVariableType.OSS] : []), - ...(hasCurrentSchema ? [PromptVariableType.SCHEMA] : []), + ...(hasCurrentSchema + ? [ + PromptVariableType.SCHEMA, // + PromptVariableType.SCHEMA_THESAURUS, + PromptVariableType.SCHEMA_GRAPH, + PromptVariableType.SCHEMA_TYPE_GRAPH + ] + : []), ...(hasCurrentBlock ? [PromptVariableType.BLOCK] : []), - ...(hasCurrentConstituenta ? [PromptVariableType.CONSTITUENTA] : []) + ...(hasCurrentConstituenta + ? [ + PromptVariableType.CONSTITUENTA, // + PromptVariableType.CONSTITUENTA_SYNTAX_TREE + ] + : []) ]; } diff --git a/rsconcept/frontend/src/features/help/items/ui/help-rsmenu.tsx b/rsconcept/frontend/src/features/help/items/ui/help-rsmenu.tsx index 9b40d796..920d637f 100644 --- a/rsconcept/frontend/src/features/help/items/ui/help-rsmenu.tsx +++ b/rsconcept/frontend/src/features/help/items/ui/help-rsmenu.tsx @@ -12,7 +12,6 @@ import { IconOwner, IconQR, IconReader, - IconRobot, IconShare, IconUpload } from '@/components/icons'; @@ -59,9 +58,6 @@ export function HelpRSMenu() {
  • Отобразить QR-код схемы
  • -
  • - Генерировать запрос для LLM -
  • Клонировать – создать копию схемы
  • diff --git a/rsconcept/frontend/src/features/rsform/pages/rsform-page/menu-main.tsx b/rsconcept/frontend/src/features/rsform/pages/rsform-page/menu-main.tsx index 8c2c8754..a8d0c030 100644 --- a/rsconcept/frontend/src/features/rsform/pages/rsform-page/menu-main.tsx +++ b/rsconcept/frontend/src/features/rsform/pages/rsform-page/menu-main.tsx @@ -1,4 +1,3 @@ -import { toast } from 'react-toastify'; import fileDownload from 'js-file-download'; import { urls, useConceptNavigation } from '@/app'; @@ -18,20 +17,18 @@ import { IconNewItem, IconOSS, IconQR, - IconRobot, IconShare, IconUpload } from '@/components/icons'; import { useDialogsStore } from '@/stores/dialogs'; import { useModificationStore } from '@/stores/modification'; import { EXTEOR_TRS_FILE } from '@/utils/constants'; -import { infoMsg, tooltipText } from '@/utils/labels'; +import { tooltipText } from '@/utils/labels'; import { type RO } from '@/utils/meta'; import { generatePageQR, promptUnsaved, sharePage } from '@/utils/utils'; import { useDownloadRSForm } from '../../backend/use-download-rsform'; import { useMutatingRSForm } from '../../backend/use-mutating-rsform'; -import { generatePrompt } from '../../models/rslang-api'; import { useRSEdit } from './rsedit-context'; @@ -111,16 +108,6 @@ export function MenuMain() { sharePage(); } - function handleCopyPrompt() { - menu.hide(); - - const prompt = generatePrompt(schema); - navigator.clipboard - .writeText(prompt) - .then(() => toast.success(infoMsg.promptReady)) - .catch(console.error); - } - function handleShowQR() { menu.hide(); showQR({ target: generatePageQR() }); @@ -152,12 +139,6 @@ export function MenuMain() { icon={} onClick={handleShowQR} /> - } - onClick={handleCopyPrompt} - /> {!isAnonymous ? (