From 4af7ddcd27bb6338e67deabbd76c466bf2f3569a Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Fri, 7 Feb 2025 15:21:59 +0100 Subject: [PATCH 1/4] Add method signatures to matrix client --- packages/host/app/services/matrix-sdk-loader.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/host/app/services/matrix-sdk-loader.ts b/packages/host/app/services/matrix-sdk-loader.ts index 97afc9797b..060a3a6d08 100644 --- a/packages/host/app/services/matrix-sdk-loader.ts +++ b/packages/host/app/services/matrix-sdk-loader.ts @@ -113,6 +113,11 @@ export type ExtendedClient = Pick< ): Promise; createRealmSession(realmURL: URL): Promise; hashMessageWithSecret(message: string): Promise; + uploadContent( + file: MatrixSDK.FileType, + opts: MatrixSDK.UploadOpts, + ): Promise; + mxcUrlToHttp(mxcUrl: string): string; }; async function hashMessageWithSecret( From 457ad379d6bd20324a8a05a741153f2e826c1b8d Mon Sep 17 00:00:00 2001 From: Matic Jurglic Date: Fri, 7 Feb 2025 15:25:26 +0100 Subject: [PATCH 2/4] Implement file attachment upload --- packages/base/file-api.gts | 51 +++++++++++++++++ packages/base/matrix-event.gts | 4 ++ .../ai-assistant/card-picker/index.gts | 17 +++++- packages/host/app/components/matrix/room.gts | 57 ++++++++++++++++++- packages/host/app/services/matrix-service.ts | 39 ++++++++++++- 5 files changed, 164 insertions(+), 4 deletions(-) create mode 100644 packages/base/file-api.gts diff --git a/packages/base/file-api.gts b/packages/base/file-api.gts new file mode 100644 index 0000000000..8e40beef1f --- /dev/null +++ b/packages/base/file-api.gts @@ -0,0 +1,51 @@ +import FileIcon from '@cardstack/boxel-icons/file'; +import { + BaseDef, + BaseDefComponent, + Component, + StringField, + contains, + field, +} from './card-api'; + +class View extends Component { + +} + +export class FileDef extends BaseDef { + static displayName = 'File'; + static icon = FileIcon; + + @field sourceUrl = contains(StringField); + @field url = contains(StringField); + @field name = contains(StringField); + @field type = contains(StringField); + + static embedded: BaseDefComponent = View; + static fitted: BaseDefComponent = View; + static isolated: BaseDefComponent = View; + static atom: BaseDefComponent = View; + + serialize() { + return { + sourceUrl: this.sourceUrl, + url: this.url, + name: this.name, + type: this.type, + }; + } +} + +export function createFileDef({ + url, + sourceUrl, + name, +}: { + url: string; + sourceUrl: string; + name: string; +}) { + return new FileDef({ url, sourceUrl, name }); +} diff --git a/packages/base/matrix-event.gts b/packages/base/matrix-event.gts index ee1cd1d55b..950073c3f1 100644 --- a/packages/base/matrix-event.gts +++ b/packages/base/matrix-event.gts @@ -192,6 +192,10 @@ export interface CardMessageContent { // fragments that we receive attachedCards?: LooseSingleCardDocument[]; skillCards?: LooseSingleCardDocument[]; + attachedFiles?: { + url: string; + name: string; + }[]; context: { openCardIds?: string[]; tools: Tool[]; diff --git a/packages/host/app/components/ai-assistant/card-picker/index.gts b/packages/host/app/components/ai-assistant/card-picker/index.gts index fbe07af34c..2e3154506c 100644 --- a/packages/host/app/components/ai-assistant/card-picker/index.gts +++ b/packages/host/app/components/ai-assistant/card-picker/index.gts @@ -10,16 +10,19 @@ import { TrackedSet } from 'tracked-built-ins'; import { AddButton, Tooltip, Pill } from '@cardstack/boxel-ui/components'; import { and, cn, gt, not } from '@cardstack/boxel-ui/helpers'; +import FileCode from '@cardstack/boxel-icons/file-code'; + import { chooseCard, baseCardRef } from '@cardstack/runtime-common'; import CardPill from '@cardstack/host/components/card-pill'; import { type CardDef } from 'https://cardstack.com/base/card-api'; - +import { type FileDef } from 'https://cardstack.com/base/file-api'; interface Signature { Element: HTMLDivElement; Args: { autoAttachedCards?: TrackedSet; + attachedFiles?: FileDef[]; cardsToAttach: CardDef[] | undefined; chooseCard: (card: CardDef) => void; removeCard: (card: CardDef) => void; @@ -31,6 +34,18 @@ const MAX_CARDS_TO_DISPLAY = 4; export default class AiAssistantCardPicker extends Component {