snapshot of https://github.com/tldraw/tldraw.git (main, 2026-09-23; blobs > 131072B omitted)
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
Some checks failed
Deploy analytics worker / Deploy analytics worker to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
i18n upload strings / Upload latest strings (push) Failing after 1s
Deploy bemo / Deploy bemo to ${{ (github.ref == 'refs/heads/bemo-production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Failing after 1s
Deploy grafana resources / ${{ github.event_name == 'push' && 'Deploy grafana resources' || 'Validate grafana resources (dry run)' }} (push) Failing after 0s
End to end tests (dotcom) / Check for relevant changes (push) Failing after 0s
End to end tests (examples) / Check for relevant changes (push) Failing after 0s
End to end tests (mermaid readability) / Check for relevant changes (push) Failing after 1s
End to end tests (perf) / Check for relevant changes (push) Failing after 0s
Publish editor extensions / Publish editor extensions (push) Failing after 1s
Publish SDK packages / Remove the publish-packages label (push) Has been skipped
Checks / Tests & checks (push) Has been cancelled
Checks / Build all projects (push) Has been cancelled
Deploy templates / Deploy templates (push) Has been cancelled
End to end tests (dotcom) / End to end tests (dotcom) (push) Has been cancelled
End to end tests (mermaid readability) / End to end tests (mermaid readability) (push) Has been cancelled
End to end tests (perf) / End to end tests (perf) (push) Has been cancelled
Deploy .com / Deploy dotcom to ${{ (github.ref == 'refs/heads/production' && 'production') || (github.ref == 'refs/heads/main' && 'staging') || 'preview' }} (push) Has been cancelled
End to end tests (examples) / End to end tests (examples) (push) Has been cancelled
Publish SDK packages / Publish SDK packages (push) Has been cancelled
Publish SDK packages / Tell user released version (push) Has been cancelled
Publish SDK packages / Publishes code templates to separate repositories (push) Has been cancelled
Publish SDK packages / Deploys the template demos with the new SDK version (push) Has been cancelled
This commit is contained in:
149
templates/agent/client/components/ChatInput.tsx
Normal file
149
templates/agent/client/components/ChatInput.tsx
Normal file
@@ -0,0 +1,149 @@
|
||||
import { FormEventHandler, useState } from 'react'
|
||||
import { Editor, useValue } from 'tldraw'
|
||||
import { AtIcon } from '../../shared/icons/AtIcon'
|
||||
import { BrainIcon } from '../../shared/icons/BrainIcon'
|
||||
import { ChevronDownIcon } from '../../shared/icons/ChevronDownIcon'
|
||||
import { AGENT_MODEL_DEFINITIONS, AgentModelName } from '../../shared/models'
|
||||
import { useAgent } from '../agent/TldrawAgentAppProvider'
|
||||
import { ContextItemTag } from './ContextItemTag'
|
||||
import { SelectionTag } from './SelectionTag'
|
||||
|
||||
export function ChatInput({
|
||||
handleSubmit,
|
||||
inputRef,
|
||||
}: {
|
||||
handleSubmit: FormEventHandler<HTMLFormElement>
|
||||
inputRef: React.RefObject<HTMLTextAreaElement | null>
|
||||
}) {
|
||||
const agent = useAgent()
|
||||
const { editor } = agent
|
||||
const [inputValue, setInputValue] = useState('')
|
||||
const isGenerating = useValue('isGenerating', () => agent.requests.isGenerating(), [agent])
|
||||
|
||||
const isContextToolActive = useValue(
|
||||
'isContextToolActive',
|
||||
() => {
|
||||
const tool = editor.getCurrentTool()
|
||||
return tool.id === 'target-shape' || tool.id === 'target-area'
|
||||
},
|
||||
[editor]
|
||||
)
|
||||
|
||||
const selectedShapes = useValue('selectedShapes', () => editor.getSelectedShapes(), [editor])
|
||||
const contextItems = useValue('contextItems', () => agent.context.getItems(), [agent])
|
||||
const modelName = useValue('modelName', () => agent.modelName.getModelName(), [agent])
|
||||
|
||||
return (
|
||||
<div className="chat-input">
|
||||
<form
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
setInputValue('')
|
||||
handleSubmit(e)
|
||||
}}
|
||||
>
|
||||
<div className="prompt-tags">
|
||||
<div className={'chat-context-select ' + (isContextToolActive ? 'active' : '')}>
|
||||
<div className="chat-context-select-label">
|
||||
<AtIcon /> Add Context
|
||||
</div>
|
||||
<select
|
||||
id="chat-context-select"
|
||||
value=" "
|
||||
onChange={(e) => {
|
||||
const action = ADD_CONTEXT_ACTIONS.find((action) => action.name === e.target.value)
|
||||
if (action) action.onSelect(editor)
|
||||
}}
|
||||
>
|
||||
{ADD_CONTEXT_ACTIONS.map((action) => {
|
||||
return (
|
||||
<option key={action.name} value={action.name}>
|
||||
{action.name}
|
||||
</option>
|
||||
)
|
||||
})}
|
||||
</select>
|
||||
</div>
|
||||
{selectedShapes.length > 0 && <SelectionTag onClick={() => editor.selectNone()} />}
|
||||
{contextItems.map((item, i) => (
|
||||
<ContextItemTag
|
||||
editor={editor}
|
||||
onClick={() => agent.context.remove(item)}
|
||||
key={'context-item-' + i}
|
||||
item={item}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<textarea
|
||||
ref={inputRef}
|
||||
name="input"
|
||||
autoComplete="off"
|
||||
placeholder="Ask, learn, brainstorm, draw"
|
||||
value={inputValue}
|
||||
onInput={(e) => setInputValue(e.currentTarget.value)}
|
||||
onKeyDown={(e) => {
|
||||
if (e.key === 'Enter' && !e.shiftKey) {
|
||||
e.preventDefault()
|
||||
//idk about this but it works oops -max
|
||||
const form = e.currentTarget.closest('form')
|
||||
if (form) {
|
||||
const submitEvent = new Event('submit', { bubbles: true, cancelable: true })
|
||||
form.dispatchEvent(submitEvent)
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
<span className="chat-actions">
|
||||
<div className="chat-actions-left">
|
||||
<div className="chat-model-select">
|
||||
<div className="chat-model-select-label">
|
||||
<BrainIcon /> {modelName}
|
||||
</div>
|
||||
<select
|
||||
value={modelName}
|
||||
onChange={(e) => agent.modelName.setModelName(e.target.value as AgentModelName)}
|
||||
>
|
||||
{Object.values(AGENT_MODEL_DEFINITIONS).map((model) => (
|
||||
<option key={model.name} value={model.name}>
|
||||
{model.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<ChevronDownIcon />
|
||||
</div>
|
||||
</div>
|
||||
<button className="chat-input-submit" disabled={inputValue === '' && !isGenerating}>
|
||||
{isGenerating && inputValue === '' ? '◼' : '⬆'}
|
||||
</button>
|
||||
</span>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
const ADD_CONTEXT_ACTIONS = [
|
||||
{
|
||||
name: 'Pick Shapes',
|
||||
onSelect: (editor: Editor) => {
|
||||
editor.setCurrentTool('target-shape')
|
||||
editor.focus()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Pick Area',
|
||||
onSelect: (editor: Editor) => {
|
||||
editor.setCurrentTool('target-area')
|
||||
editor.focus()
|
||||
},
|
||||
},
|
||||
{
|
||||
name: ' ',
|
||||
onSelect: (editor: Editor) => {
|
||||
const currentTool = editor.getCurrentTool()
|
||||
if (currentTool.id === 'target-area' || currentTool.id === 'target-shape') {
|
||||
editor.setCurrentTool('select')
|
||||
}
|
||||
},
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user