import type { DeclaredOutputConfig } from '@dify/contracts/api/console/apps/types.gen' import type { LexicalNode, NodeKey, SerializedLexicalNode } from 'lexical' import type { AgentOutputTypeOptionValue } from './utils' import { DecoratorNode } from 'lexical' import AgentOutputBlockComponent from './component' import { getAgentOutputToken } from './utils' type SerializedNode = SerializedLexicalNode & { name: string outputType: AgentOutputTypeOptionValue } export class AgentOutputBlockNode extends DecoratorNode { __name: string __outputType: AgentOutputTypeOptionValue __isEditing: boolean __selectNameOnEdit: boolean __openTypeSelectOnEdit: boolean __outputs: DeclaredOutputConfig[] __onChange?: (outputs: DeclaredOutputConfig[], prompt?: string) => void __onEdit?: (name: string, outputType: AgentOutputTypeOptionValue) => void static override getType(): string { return 'agent-output-block' } static override clone(node: AgentOutputBlockNode): AgentOutputBlockNode { return new AgentOutputBlockNode( node.__name, node.__outputType, node.__isEditing, node.__selectNameOnEdit, node.__openTypeSelectOnEdit, node.__outputs, node.__onChange, node.__onEdit, node.__key, ) } override isInline(): boolean { return true } constructor( name: string, outputType: AgentOutputTypeOptionValue, isEditing = false, selectNameOnEdit = isEditing, openTypeSelectOnEdit = false, outputs: DeclaredOutputConfig[] = [], onChange?: (outputs: DeclaredOutputConfig[], prompt?: string) => void, onEdit?: (name: string, outputType: AgentOutputTypeOptionValue) => void, key?: NodeKey, ) { super(key) this.__name = name this.__outputType = outputType this.__isEditing = isEditing this.__selectNameOnEdit = selectNameOnEdit this.__openTypeSelectOnEdit = openTypeSelectOnEdit this.__outputs = outputs this.__onChange = onChange this.__onEdit = onEdit } override createDOM(): HTMLElement { const div = document.createElement('div') div.classList.add('inline-flex', 'items-center', 'align-middle') return div } override updateDOM(): false { return false } override decorate(): React.JSX.Element { return ( ) } static override importJSON(serializedNode: SerializedNode): AgentOutputBlockNode { return $createAgentOutputBlockNode(serializedNode.name, serializedNode.outputType) } override exportJSON(): SerializedNode { return { type: 'agent-output-block', version: 1, name: this.getName(), outputType: this.getOutputType(), } } getName(): string { return this.getLatest().__name } getOutputType(): AgentOutputTypeOptionValue { return this.getLatest().__outputType } isEditing(): boolean { return this.getLatest().__isEditing } shouldSelectNameOnEdit(): boolean { return this.getLatest().__selectNameOnEdit } shouldOpenTypeSelectOnEdit(): boolean { return this.getLatest().__openTypeSelectOnEdit } getOutputs(): DeclaredOutputConfig[] { return this.getLatest().__outputs } getOnChange(): ((outputs: DeclaredOutputConfig[], prompt?: string) => void) | undefined { return this.getLatest().__onChange } getOnEdit(): ((name: string, outputType: AgentOutputTypeOptionValue) => void) | undefined { return this.getLatest().__onEdit } setOutput( name: string, outputType: AgentOutputTypeOptionValue, isEditing: boolean, outputs: DeclaredOutputConfig[], onChange?: (outputs: DeclaredOutputConfig[], prompt?: string) => void, onEdit?: (name: string, outputType: AgentOutputTypeOptionValue) => void, selectNameOnEdit = false, openTypeSelectOnEdit = false, ): this { const writable = this.getWritable() writable.__name = name writable.__outputType = outputType writable.__isEditing = isEditing writable.__selectNameOnEdit = selectNameOnEdit writable.__openTypeSelectOnEdit = openTypeSelectOnEdit writable.__outputs = outputs writable.__onChange = onChange writable.__onEdit = onEdit return writable } setOpenTypeSelectOnEdit(openTypeSelectOnEdit: boolean): this { const writable = this.getWritable() writable.__openTypeSelectOnEdit = openTypeSelectOnEdit return writable } override getTextContent(): string { return getAgentOutputToken(this.getName()) } } export function $createAgentOutputBlockNode( name: string, outputType: AgentOutputTypeOptionValue = 'string', isEditing = false, outputs: DeclaredOutputConfig[] = [], onChange?: (outputs: DeclaredOutputConfig[], prompt?: string) => void, onEdit?: (name: string, outputType: AgentOutputTypeOptionValue) => void, selectNameOnEdit = isEditing, openTypeSelectOnEdit = false, ): AgentOutputBlockNode { return new AgentOutputBlockNode( name, outputType, isEditing, selectNameOnEdit, openTypeSelectOnEdit, outputs, onChange, onEdit, ) } export function $isAgentOutputBlockNode( node: AgentOutputBlockNode | LexicalNode | null | undefined, ): node is AgentOutputBlockNode { return node instanceof AgentOutputBlockNode }