Add bots files handling logic

This commit is contained in:
2026-10-21 17:56:09 +01:00
parent b0af4db1bf
commit d17a4a7bdd
97 changed files with 5843 additions and 41 deletions
+102
View File
@@ -0,0 +1,102 @@
/**
* Where a bot file lives: a bot's own directory (`DATA_DIR/bots/<id>`) or
* a workspace's shared one (`DATA_DIR/workspaces/<id>`), which the bots
* working there and the coordinator reach.
*/
export const BotFileScopes = [
{
title: "Bot",
value: "bot",
},
{
title: "Workspace",
value: "workspace",
},
] as const;
export type BotFileScope = (typeof BotFileScopes)[number]["value"];
/**
* What a file is for. Only the display and the icon use it; the bot picks
* it when it writes one.
*/
export const BotFilePurposes = [
{
title: "Upload",
value: "upload",
},
{
title: "Writing",
value: "writing",
},
{
title: "Image",
value: "image",
},
{
title: "PDF",
value: "pdf",
},
{
title: "Artifact",
value: "artifact",
},
] as const;
export type BotFilePurpose = (typeof BotFilePurposes)[number]["value"];
/**
* How a file got into the bot's storage.
*/
export const BotFileSources = [
{
title: "Chat upload",
value: "chat-upload",
},
{
title: "Bot write",
value: "bot-write",
},
{
title: "Tool",
value: "tool",
},
] as const;
export type BotFileSource = (typeof BotFileSources)[number]["value"];
/**
* The `app_settings` key holding the per-owner storage quota, in MB.
*/
export const BotFileQuotaSettingKey = "bot_files_quota_mb";
/**
* The top folder chat uploads land in, under the conversation's scope.
*/
export const BotUploadFolder = "uploads";
/**
* Extensions a bot's text extraction reads without a model: documents
* that are already text once unpacked.
*/
export const BotTextFileExtensions = [
"txt",
"md",
"markdown",
"csv",
"json",
"html",
"htm",
"xml",
"yml",
"yaml",
"log",
"tsv",
"pdf",
"docx",
] as const;
/**
* What a file's extension says it is, for the storage row and the icon.
*/
export const BotImageFileExtensions = ["png", "jpg", "jpeg", "webp", "gif", "bmp", "svg"];
+10 -2
View File
@@ -2,8 +2,9 @@
* The harnesses: what a model is used for. Each harness has one model
* setting (`harness_settings`). Text is the brain and can't be turned off;
* the others are helpers it calls on. `automatic` ones pick a free model
* themselves when none is picked; the rest (transcription, speech) are
* not available until one is, since free picks there rarely work.
* themselves when none is picked; the rest (transcription, speech,
* embeddings) are not available until one is, since free picks there
* rarely work.
*/
export const Harnesses = [
{
@@ -41,6 +42,13 @@ export const Harnesses = [
description: `Makes images when a bot is asked for one.`,
required: false,
},
{
title: "Embeddings",
value: "embedding",
automatic: false,
description: `Turns the files bots save into vectors, so they can search them. Without one, searching falls back to plain text matching.`,
required: false,
},
] as const;
export type HarnessKind = (typeof Harnesses)[number]["value"];
+4
View File
@@ -42,4 +42,8 @@ export const MediaParadigms = [
title: "Workspace Image",
value: "workspace-image",
},
{
title: "Bot File",
value: "bot-file",
},
] as const;