diff --git a/.gitignore b/.gitignore index 638075ac..49dad48e 100644 --- a/.gitignore +++ b/.gitignore @@ -70,6 +70,7 @@ shell.nix **/.jekyll-cache .beaker.conf +.beaker/session-attachments/ beaker_config.py beaker_*_config.py src/beaker_notebook/**/ui/* diff --git a/beaker-ts/src/notebook.ts b/beaker-ts/src/notebook.ts index f7cc5934..b499c399 100644 --- a/beaker-ts/src/notebook.ts +++ b/beaker-ts/src/notebook.ts @@ -196,6 +196,22 @@ export type BeakerQueryEvent = export interface IQueryCell extends nbformat.IBaseCell { cell_type: 'query'; events: BeakerQueryEvent[]; + session_attachments?: ISessionAttachment[]; +} + +export interface ISessionAttachment extends PartialJSONObject { + id: string; + name: string; + mimetype: string; + size: number; + kind: "file" | "archive"; + path?: string | null; + root_path: string; + original_path?: string | null; + archive_status?: "extracted" | "failed" | null; + archive_error?: string | null; + file_count: number; + files: string[]; } export class BeakerRawCell extends BeakerBaseCell implements nbformat.IRawCell { @@ -335,6 +351,8 @@ export class BeakerMarkdownCell extends BeakerBaseCell implements nbformat.IMark export class BeakerQueryCell extends BeakerBaseCell implements IQueryCell { cell_type: "query" = "query"; events: BeakerQueryEvent[] = []; + /** Live-session chat attachments. Intentionally omitted from notebook serialization. */ + session_attachments: ISessionAttachment[] = []; _current_input_request_message?: messages.IInputRequestMsg; _toolCallIndex: Map = new Map(); @@ -564,7 +582,8 @@ export class BeakerQueryCell extends BeakerBaseCell implements IQueryCell { const future = session.sendBeakerMessage( "llm_request", { - request: this.source + request: this.source, + attachments: this.session_attachments.map((attachment) => attachment.id), }, undefined, metadata, diff --git a/beaker-ts/src/session.ts b/beaker-ts/src/session.ts index a4eaf629..d1c9b4f6 100644 --- a/beaker-ts/src/session.ts +++ b/beaker-ts/src/session.ts @@ -10,7 +10,7 @@ import * as nbformat from '@jupyterlab/nbformat'; import type { ConnectionStatus as JupyterConnectionStatus, IAnyMessageArgs } from '@jupyterlab/services/lib/kernel/kernel'; import { createMessageId, IBeakerAvailableContexts, IBeakerFuture, IActiveContextInfo } from './util'; -import { BeakerNotebook, IBeakerShellMessage, IBeakerAnyMessage, BeakerRawCell, BeakerCodeCell, BeakerMarkdownCell, BeakerQueryCell, IBeakerIOPubMessage } from './notebook'; +import { BeakerNotebook, IBeakerShellMessage, IBeakerAnyMessage, BeakerRawCell, BeakerCodeCell, BeakerMarkdownCell, BeakerQueryCell, IBeakerIOPubMessage, ISessionAttachment } from './notebook'; import { BeakerHistory } from './history'; import { BeakerRenderer, type IBeakerRendererOptions } from './render'; import { ChatHistory, type IChatHistory } from './chatHistory'; @@ -390,12 +390,13 @@ export class BeakerSession { * @param metadata - (Optional) Any metadata to be associated with the cell. * @returns - A reference to the generated cell */ - public addQueryCell(source: string, metadata={}) { + public addQueryCell(source: string, metadata={}, sessionAttachments: ISessionAttachment[] = []) { const cell = new BeakerQueryCell({ cell_type: "query", source, metadata, }); + cell.session_attachments = sessionAttachments; this.notebook.addCell(cell); return cell; }; diff --git a/beaker-vue/src/components/agent/BeakerAgentQuery.vue b/beaker-vue/src/components/agent/BeakerAgentQuery.vue index 011d5b07..1f8819dd 100644 --- a/beaker-vue/src/components/agent/BeakerAgentQuery.vue +++ b/beaker-vue/src/components/agent/BeakerAgentQuery.vue @@ -1,5 +1,16 @@