import { BaseBoxShapeUtil, HTMLContainer, // TLArrowShape, TLBaseShape, TLGeoShape, TLOnResizeHandler, TLShape, } from "tldraw" import { getEdge } from "./propagators/tlgraph" import { llm } from "./llm" import { isShapeOfType } from "./propagators/utils" import { ISocialShape } from "./SocialShapeUtil" // import TextInput from "react-autocomplete-input" // import "react-autocomplete-input/dist/bundle.css" type IPrompt = TLBaseShape< "prompt", { w: number h: number prompt: string output: string agentBinding: string | null } > export class PromptShape extends BaseBoxShapeUtil { static override type = "prompt" as const FIXED_HEIGHT = 50 as const MIN_WIDTH = 150 as const PADDING = 4 as const getDefaultProps(): IPrompt["props"] { return { w: 300, h: 50, prompt: "", output: "", agentBinding: null, } } override onResize: TLOnResizeHandler = ( shape, { scaleX, initialShape }, ) => { const { x, y } = shape const w = initialShape.props.w * scaleX return { x, y, props: { ...shape.props, w: Math.max(Math.abs(w), this.MIN_WIDTH), h: this.FIXED_HEIGHT, }, } } component(shape: IPrompt) { const arrowBindings = this.editor.getBindingsInvolvingShape( shape.id, "arrow", ) const arrows = arrowBindings .map((binding) => this.editor.getShape(binding.fromId)) const inputMap = arrows.reduce((acc, arrow) => { const edge = getEdge(arrow, this.editor); if (edge) { const sourceShape = this.editor.getShape(edge.from); if (sourceShape && edge.text) { acc[edge.text] = sourceShape; } } return acc; }, {} as Record); const generateText = async (prompt: string) => { await llm('', prompt, (partial: string, done: boolean) => { console.log("DONE??", done) this.editor.updateShape({ id: shape.id, type: "prompt", props: { output: partial, agentBinding: done ? null : 'someone' }, }) }) } const handlePrompt = () => { let processedPrompt = shape.props.prompt; for (const [key, sourceShape] of Object.entries(inputMap)) { const pattern = `{${key}}`; if (processedPrompt.includes(pattern)) { if (isShapeOfType(sourceShape, 'geo')) { processedPrompt = processedPrompt.replace(pattern, sourceShape.props.text); } else if (isShapeOfType(sourceShape, 'social')) { processedPrompt = processedPrompt.replace(pattern, sourceShape.props.value.toString()); } } } console.log(processedPrompt); generateText(processedPrompt) }; return ( { this.editor.updateShape({ id: shape.id, type: "prompt", props: { prompt: text.target.value }, }) }} /> ) } // [5] indicator(shape: IPrompt) { return } }