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
111 lines
3.3 KiB
TypeScript
111 lines
3.3 KiB
TypeScript
import { squashRecordDiffs } from 'tldraw'
|
|
import {
|
|
convertTldrawIdToSimpleId,
|
|
convertTldrawShapeToFocusedShape,
|
|
convertTldrawShapeToFocusedType,
|
|
} from '../../shared/format/convertTldrawShapeToFocusedShape'
|
|
import { FocusedShape } from '../../shared/format/FocusedShape'
|
|
import { UserActionHistoryPart } from '../../shared/schema/PromptPartDefinitions'
|
|
import { AgentRequest } from '../../shared/types/AgentRequest'
|
|
import { AgentHelpers } from '../AgentHelpers'
|
|
import { PromptPartUtil, registerPromptPartUtil } from './PromptPartUtil'
|
|
|
|
export const UserActionHistoryPartUtil = registerPromptPartUtil(
|
|
class UserActionHistoryPartUtil extends PromptPartUtil<UserActionHistoryPart> {
|
|
static override type = 'userActionHistory' as const
|
|
|
|
override getPart(_request: AgentRequest, helpers: AgentHelpers): UserActionHistoryPart {
|
|
const { editor, agent } = helpers
|
|
|
|
// Get the action history and clear it so that we can start tracking changes for the next request
|
|
const diffs = agent.userAction.getHistory()
|
|
agent.userAction.clearHistory()
|
|
|
|
const part: UserActionHistoryPart = {
|
|
type: 'userActionHistory',
|
|
added: [],
|
|
removed: [],
|
|
updated: [],
|
|
}
|
|
|
|
const squashedDiff = squashRecordDiffs(diffs)
|
|
const { added, updated, removed } = squashedDiff
|
|
|
|
// Collect user-added shapes
|
|
for (const shape of Object.values(added)) {
|
|
if (shape.typeName !== 'shape') continue
|
|
part.added.push({
|
|
shapeId: convertTldrawIdToSimpleId(shape.id),
|
|
type: convertTldrawShapeToFocusedType(shape),
|
|
})
|
|
}
|
|
|
|
// Collect user-removed shapes
|
|
for (const shape of Object.values(removed)) {
|
|
if (shape.typeName !== 'shape') continue
|
|
const focusedShape = convertTldrawShapeToFocusedShape(editor, shape)
|
|
part.removed.push({
|
|
shapeId: focusedShape.shapeId,
|
|
type: focusedShape._type,
|
|
})
|
|
}
|
|
|
|
// Collect user-updated shapes
|
|
for (const [from, to] of Object.values(updated)) {
|
|
if (from.typeName !== 'shape' || to.typeName !== 'shape') continue
|
|
const fromFocusedShape = convertTldrawShapeToFocusedShape(editor, from)
|
|
const toFocusedShape = convertTldrawShapeToFocusedShape(editor, to)
|
|
|
|
const changeFocusedShape = getFocusedShapeChange(fromFocusedShape, toFocusedShape)
|
|
if (!changeFocusedShape) continue
|
|
|
|
const before = helpers.applyOffsetToShapePartial(changeFocusedShape.from)
|
|
const after = helpers.applyOffsetToShapePartial(changeFocusedShape.to)
|
|
|
|
part.updated.push({
|
|
shapeId: toFocusedShape.shapeId,
|
|
type: toFocusedShape._type,
|
|
before: helpers.roundShapePartial(before),
|
|
after: helpers.roundShapePartial(after),
|
|
})
|
|
}
|
|
|
|
return part
|
|
}
|
|
}
|
|
)
|
|
|
|
/**
|
|
* Get any changed properties between two focused shapes.
|
|
* @param from - The original shape.
|
|
* @param to - The new shape.
|
|
* @returns The changed properties.
|
|
*/
|
|
function getFocusedShapeChange<T extends FocusedShape['_type']>(
|
|
from: FocusedShape & { _type: T },
|
|
to: FocusedShape & { _type: T }
|
|
) {
|
|
if (from._type !== to._type) {
|
|
return null
|
|
}
|
|
|
|
const change: {
|
|
from: Partial<FocusedShape>
|
|
to: Partial<FocusedShape>
|
|
} = {
|
|
from: {},
|
|
to: {},
|
|
}
|
|
|
|
for (const key in to) {
|
|
const fromValue = from[key]
|
|
const toValue = to[key]
|
|
if (fromValue === toValue) {
|
|
continue
|
|
}
|
|
;(change.from as any)[key] = fromValue
|
|
;(change.to as any)[key] = toValue
|
|
}
|
|
return change
|
|
}
|