The longest runbook a skill may save and how much of it load_skill hands back are now set on Settings > General (skill_body_max_chars, skill_body_shown_chars), defaulting to AppData.SkillBodyMaxChars and SkillBodyShownChars. Saving, confirming and proposing a skill check the install's limit; a skill saved before it was lowered can still be toggled. Co-Authored-By: Claude Opus 5.5 <[email protected]>
642 lines
23 KiB
TypeScript
642 lines
23 KiB
TypeScript
import { SiteData } from "./site-data";
|
|
|
|
export const AppData = {
|
|
HashCost: 12,
|
|
/**
|
|
* Shared with twui's `ColorSchemeSelector`, so it must stay `theme`.
|
|
*/
|
|
ThemeStorageKey: "theme",
|
|
/**
|
|
* How many of a build's files the loading page downloads at once.
|
|
*/
|
|
PrecacheConcurrency: 6,
|
|
/**
|
|
* How many more times the loading page downloads files it finds
|
|
* missing from the cache after a pass, before it gives up on them.
|
|
*/
|
|
PrecacheVerifyPasses: 2,
|
|
/**
|
|
* How long the loading page waits for a new service worker to take
|
|
* over before it reloads into the app anyway.
|
|
*/
|
|
PrecacheWorkerWaitMs: 10_000,
|
|
/**
|
|
* The loading page gives up and lets the app run from the network
|
|
* when no new file lands for this long.
|
|
*/
|
|
PrecacheStallMs: 30_000,
|
|
/**
|
|
* Prefix of the composer's unsent drafts in `localStorage`, one per
|
|
* bot and workspace.
|
|
*/
|
|
ComposerDraftStorageKey: `${SiteData["SiteSlug"]}_composer_draft`,
|
|
/**
|
|
* Prefix of the chat header's model data in `localStorage`: one catalog
|
|
* per user, and one small setting per bot and workspace.
|
|
* `HarnessCatalogCacheMs` is how long the catalog is shown before it is
|
|
* fetched again, `HarnessOverviewCacheMs` the setting.
|
|
*/
|
|
HarnessCacheStorageKey: `${SiteData["SiteSlug"]}_harness_cache`,
|
|
HarnessCatalogCacheMs: 60 * 60 * 1000,
|
|
/**
|
|
* The per-conversation key an older version wrote. Removed on logout
|
|
* and by `clearHarnessCache`.
|
|
*/
|
|
LegacyHarnessOverviewStorageKey: `${SiteData["SiteSlug"]}_harness_overview`,
|
|
HarnessOverviewCacheMs: 10 * 60 * 1000,
|
|
ServerHealthMessage: "Server Running Well",
|
|
AuthKeyCookieName: `${SiteData["SiteSlug"]}_auth_key`,
|
|
AuthCSRFCookieName: `${SiteData["SiteSlug"]}_auth_csrf`,
|
|
/**
|
|
* The build this browser has been through the loading page for
|
|
* (`handlePrecacheGate`). Set by the page itself, so not `HttpOnly`;
|
|
* it holds nothing private.
|
|
*/
|
|
BuildCookieName: `${SiteData["SiteSlug"]}_build`,
|
|
BuildCookieMaxAgeSeconds: 365 * 24 * 60 * 60,
|
|
/**
|
|
* The bot this browser was last in: `/admin/bots` opens its own chat
|
|
* again, falling back to the coordinator (super admin) or the latest
|
|
* bot when the grant is gone. One small id. `HttpOnly`: only the server
|
|
* reads it.
|
|
*/
|
|
LastVisitedBotCookieName: `${SiteData["SiteSlug"]}_last_visited_bot_id`,
|
|
LastVisitedCookieMaxAgeSeconds: 365 * 24 * 60 * 60,
|
|
AuthExpiryDays: 60,
|
|
APICrudBasePath: "/api/admin/crud",
|
|
ForcePrivateHeaderKey: `x-${SiteData["SiteSlug"]}-force-private`,
|
|
ForcePublicHeaderKey: `x-${SiteData["SiteSlug"]}-force-public`,
|
|
DefaultQueryLimit: 40,
|
|
MainImageSize: 500,
|
|
MaxImageWidth: 1500,
|
|
ImageThumbnailSize: 150,
|
|
ImageQuality: 85,
|
|
ImageThumbnailQuality: 70,
|
|
PaystackEndpoint: "https://api.paystack.co",
|
|
ContactFormLimit: 5,
|
|
RateLimitWindowMinutes: 15,
|
|
UsernameRegex: /^[a-z0-9._-]{3,32}$/,
|
|
PasswordMinLength: 8,
|
|
PasswordMaxLength: 128,
|
|
PasswordAttemptLimit: 10,
|
|
/**
|
|
* Docker network shared by the app and every computer. The app makes
|
|
* sure it exists on startup and before it creates a container, and
|
|
* joins it when it runs in docker.
|
|
*/
|
|
DockerNetworkName: SiteData["SiteSlug"],
|
|
/**
|
|
* Port the AIO sandbox listens on inside its container.
|
|
*/
|
|
ComputerPort: 8080,
|
|
/**
|
|
* Every computer the app creates runs this image, named
|
|
* `<ComputerContainerPrefix>-<computer id>` on `DockerNetworkName`.
|
|
*/
|
|
ComputerImage: "ghcr.io/agent-infra/sandbox:latest",
|
|
ComputerContainerPrefix: `${SiteData["SiteSlug"]}-computer`,
|
|
/**
|
|
* Only a computer's workspace (`ComputerWorkspaceDir` in its
|
|
* container) is kept, at `DATA_DIR/<ComputerDataDir>/<id>`, owned by
|
|
* the sandbox's user. It stays when the computer is deleted. The rest
|
|
* of its home (`ComputerHomeDir`: dotfiles, browser profile, the env
|
|
* files) lives in the container and goes with it. Every bot works in
|
|
* `bots/<bot id>` there, a user's work in `bots/<bot id>/users/<user
|
|
* id>`, and a workspace's bots share `workspaces/<workspace id>`
|
|
* (`computerRunDirs`).
|
|
*/
|
|
ComputerDataDir: "computers",
|
|
ComputerHomeDir: "/home/gem",
|
|
ComputerWorkspaceDir: "/home/gem/workspace",
|
|
/**
|
|
* Written at the root of a computer's workspace once it uses that
|
|
* layout, so an older computer's whole home is told apart and moved
|
|
* aside (`prepareComputerDataDir`).
|
|
*/
|
|
ComputerWorkspaceMarker: ".cobble-workspace",
|
|
/**
|
|
* An older computer's whole home is moved aside to
|
|
* `<id><ComputerOldHomeSuffix><timestamp>` and kept, never archived.
|
|
*/
|
|
ComputerOldHomeSuffix: "-home-",
|
|
/**
|
|
* Recorded in a container's `metadata.layout` once it mounts only the
|
|
* workspace.
|
|
*/
|
|
ComputerWorkspaceLayout: "workspace",
|
|
ComputerUserUid: 1000,
|
|
ComputerUserGid: 1000,
|
|
/**
|
|
* Resources a new computer's container gets, saved on the computer
|
|
* (`cpus`, `memory_mb`) when it is created.
|
|
*/
|
|
ComputerDefaultCpus: 1,
|
|
ComputerDefaultMemoryMb: 2048,
|
|
ComputerMinCpus: 0.25,
|
|
ComputerMaxCpus: 64,
|
|
ComputerMinMemoryMb: 512,
|
|
/**
|
|
* Docker's health check on every computer container: the sandbox's API
|
|
* on `ComputerPort` and its browser answer. A new computer stays
|
|
* `creating` until it passes, for at most `ComputerHealthyTimeoutMs`,
|
|
* checked every `ComputerHealthPollMs`.
|
|
*/
|
|
ComputerHealthcheck: {
|
|
IntervalSeconds: 5,
|
|
TimeoutSeconds: 5,
|
|
StartPeriodSeconds: 120,
|
|
Retries: 3,
|
|
},
|
|
ComputerHealthyTimeoutMs: 5 * 60 * 1000,
|
|
ComputerHealthPollMs: 2000,
|
|
/**
|
|
* How long docker gives a computer's container to stop before it is
|
|
* killed, when it is removed or recreated.
|
|
*/
|
|
ComputerStopTimeoutSeconds: 10,
|
|
/**
|
|
* A computer is reached at its hostname, else its IP address. Each
|
|
* address gets this long to answer, and the one that did is reused
|
|
* for `ComputerAddressCacheMs`.
|
|
*/
|
|
ComputerReachTimeoutMs: 2000,
|
|
ComputerAddressCacheMs: 60 * 1000,
|
|
/**
|
|
* Per computer container.
|
|
*/
|
|
ComputerShmBytes: 2 * 1024 * 1024 * 1024,
|
|
/**
|
|
* The docker engine API, reached over its unix socket.
|
|
*/
|
|
DockerSocketPath: "/var/run/docker.sock",
|
|
/**
|
|
* Cap on a bot's `system_prompt` and `memory`, and on a workspace's
|
|
* `system_prompt`, so self-updates can't grow a prompt without bound.
|
|
*/
|
|
PromptMaxLength: 20000,
|
|
/**
|
|
* `bots_queue` (bun-sqlite `isQueue`). A job that hasn't sent an update
|
|
* within the lock timeout is presumed lost and goes back to the queue,
|
|
* so long computer jobs must call `updateBotJob` more often than this.
|
|
*/
|
|
BotQueueMaxAttempts: 3,
|
|
BotQueueLockTimeoutMs: 10 * 60 * 1000,
|
|
BotQueueBackoffMs: 30 * 1000,
|
|
/**
|
|
* One attempt of a job (one model run or task, tools included) gives up
|
|
* after this long and counts as a failed try, so a call that hangs
|
|
* without ever answering can't hold the job, its computer or the
|
|
* conversation forever. The lock is outlived by the heartbeat, so this
|
|
* is the only thing that stops a live but stuck run.
|
|
*/
|
|
BotJobAttemptTimeoutMs: 60 * 60 * 1000,
|
|
/**
|
|
* A failed scheduled run is tried again after this, doubling each time
|
|
* (`scheduledRunRetryAt`), so a short outage doesn't sink the run.
|
|
*/
|
|
ScheduledRunRetryMs: 5 * 60 * 1000,
|
|
/**
|
|
* The queue handler's lock name. Stable across restarts, so on startup
|
|
* it can release the jobs it was running when the process stopped.
|
|
*/
|
|
BotQueueWorker: "main",
|
|
BotQueuePollMs: 3000,
|
|
/**
|
|
* Tasks run at once. Tasks on the same computer always run one at a time.
|
|
*/
|
|
BotQueueConcurrency: 3,
|
|
/**
|
|
* Chat replies run at once, on their own slots so they never wait
|
|
* behind long tasks. One per bot at a time.
|
|
*/
|
|
BotQueueReplyConcurrency: 3,
|
|
/**
|
|
* Finished jobs are deleted after this many days.
|
|
*/
|
|
BotQueueRetentionDays: 30,
|
|
/**
|
|
* A bot's schedules (`cron_jobs`): how many it can have, and the
|
|
* shortest gap between two runs, so a schedule can't flood the queue.
|
|
*/
|
|
CronJobMaxPerBot: 20,
|
|
CronJobMinIntervalMs: 5 * 60 * 1000,
|
|
/**
|
|
* Due schedules queued per tick of the `run-cron-jobs` cron.
|
|
*/
|
|
CronJobBatchSize: 50,
|
|
/**
|
|
* Tasks (the crew's to-do list, `tasks`): the longest title, brief and
|
|
* note, how many one bot or workspace can hold, and how many files one
|
|
* task carries.
|
|
*/
|
|
TaskTitleMaxLength: 120,
|
|
TaskDescriptionMaxLength: 8000,
|
|
TaskNoteMaxLength: 2000,
|
|
TaskMaxPerScope: 200,
|
|
TaskMediaMaxPerTask: 20,
|
|
/**
|
|
* Open tasks a chat reply carries as a digest for its reminder, and how
|
|
* many `list_tasks` hands back at once.
|
|
*/
|
|
TaskReminderDigestCount: 3,
|
|
TaskListToolLimit: 20,
|
|
/**
|
|
* Automatic model picks (`rankAutoModels`). A free model from outside
|
|
* `AutoModelVendorPreference` must have at least this much context, and
|
|
* this intelligence index or, unscored, this many billion parameters.
|
|
*/
|
|
HarnessAutoMinContext: 32000,
|
|
HarnessAutoMinScore: 12,
|
|
HarnessAutoMinSizeB: 20,
|
|
/**
|
|
* Models tried per harness call before giving up (pinned plus
|
|
* automatic fallbacks).
|
|
*/
|
|
HarnessMaxCandidates: 5,
|
|
HarnessRequestTimeoutMs: 3 * 60 * 1000,
|
|
/**
|
|
* One tool call gives up after this long, whatever the tool is (bot
|
|
* tools, MCP servers, computers, custom tools), so a tool that ignores
|
|
* its own limits can't stall the run. Its result comes back as an error
|
|
* the model can work around.
|
|
*/
|
|
HarnessToolTimeoutMs: 10 * 60 * 1000,
|
|
/**
|
|
* A model that rate limits or fails is skipped for this long, unless
|
|
* the provider says when to come back (capped at the max).
|
|
*/
|
|
HarnessCooldownMs: 60 * 1000,
|
|
HarnessMaxCooldownMs: 24 * 60 * 60 * 1000,
|
|
/**
|
|
* Model turns in one text run before it must stop and report. The
|
|
* install may save its own limit (the `harness_max_tool_steps` setting,
|
|
* Settings > General), which wins over this one; a task run reads it
|
|
* through `grabHarnessMaxToolSteps`.
|
|
*/
|
|
HarnessMaxToolSteps: 200,
|
|
/**
|
|
* Longest tool result handed back to the model.
|
|
*/
|
|
HarnessToolResultMaxChars: 20000,
|
|
/**
|
|
* Upload cap for audio sent to transcription.
|
|
*/
|
|
HarnessMaxAudioBytes: 25 * 1024 * 1024,
|
|
/**
|
|
* Connecting to an MCP server (a computer) gives up after this long.
|
|
*/
|
|
McpConnectTimeoutMs: 15 * 1000,
|
|
/**
|
|
* One MCP tool call gives up after this long without progress.
|
|
*/
|
|
McpToolTimeoutMs: 5 * 60 * 1000,
|
|
/**
|
|
* MCP servers set up in Settings, under MCPs: a stdio server runs in
|
|
* `DATA_DIR/<McpDataDir>/<id>` (its setup installs there, so it
|
|
* survives updates), its setup command may take `McpSetupTimeoutMs`,
|
|
* and it's stopped after `McpStdioIdleMs` without a call.
|
|
*/
|
|
McpDataDir: "mcp",
|
|
McpSetupTimeoutMs: 10 * 60 * 1000,
|
|
McpStdioIdleMs: 10 * 60 * 1000,
|
|
/**
|
|
* A custom tool (Settings, under Tools) gives up after its own timeout,
|
|
* `CustomToolDefaultTimeoutMs` when it has none, never past
|
|
* `CustomToolMaxTimeoutMs`.
|
|
*/
|
|
CustomToolDefaultTimeoutMs: 60 * 1000,
|
|
CustomToolMaxTimeoutMs: 10 * 60 * 1000,
|
|
/**
|
|
* Skills (Settings, under Skills): how long one's body may be, and how
|
|
* much of it `load_skill` hands back in one call. A runbook past that
|
|
* is worth splitting into two skills. These are the defaults: the
|
|
* install sets its own on Settings > General (`skill_body_max_chars`,
|
|
* `skill_body_shown_chars`, `grab-skill-limits.ts`), never past
|
|
* `SkillBodyLimitMax`.
|
|
*/
|
|
SkillBodyMaxChars: 60000,
|
|
SkillBodyShownChars: 30000,
|
|
SkillBodyLimitMax: 1000000,
|
|
SkillDescriptionMaxChars: 300,
|
|
/**
|
|
* How long the super admin has to confirm an MCP server or tool the
|
|
* coordinator proposed (`extension_proposals`). After that its card
|
|
* reads expired and the bot has to propose it again, so a card left in
|
|
* an old thread can't be confirmed weeks later.
|
|
*/
|
|
ExtensionProposalTtlMs: 24 * 60 * 60 * 1000,
|
|
/**
|
|
* A proposal's background check: the bot's summary, and the sources it
|
|
* read (at least one).
|
|
*/
|
|
ExtensionResearchMinChars: 40,
|
|
ExtensionResearchMaxChars: 6000,
|
|
ExtensionResearchSourcesMax: 10,
|
|
/**
|
|
* `search_computers`: how long the command may run on each computer,
|
|
* and how much of each computer's output the bot reads.
|
|
*/
|
|
ComputerSearchTimeoutMs: 30 * 1000,
|
|
ComputerSearchMaxOutputChars: 4000,
|
|
/**
|
|
* How many of a job's latest steps (`bots_queue_updates`) the
|
|
* working-on panel shows.
|
|
*/
|
|
BotJobUpdatesShown: 12,
|
|
/**
|
|
* How often each server process reads new bot messages, job steps and
|
|
* bot changes from the database for its own sockets (`liveRelay`).
|
|
*/
|
|
LiveRelayPollMs: 1500,
|
|
/**
|
|
* While a reply is due in the open conversation, how often the page
|
|
* checks for new messages itself, in case a live push was missed (the
|
|
* socket was down) and the thinking row would otherwise stay up.
|
|
*/
|
|
BotReplyCatchUpMs: 5000,
|
|
/**
|
|
* How many of a session's latest messages that check reads.
|
|
*/
|
|
BotReplyCatchUpMessages: 20,
|
|
/**
|
|
* How much of the conversation a bot sees when it replies.
|
|
*/
|
|
BotReplyHistoryMessages: 40,
|
|
/**
|
|
* How many of a session's latest messages the conversation page
|
|
* renders with; older ones load as the thread is scrolled up.
|
|
*/
|
|
ConversationFirstMessages: 30,
|
|
/**
|
|
* How many older messages each scroll to the top of the thread loads.
|
|
*/
|
|
ConversationOlderMessages: 30,
|
|
/**
|
|
* The most model calls a message's details modal lists one by one. A
|
|
* long task can take hundreds; the totals still count every one.
|
|
*/
|
|
MessageDetailsMaxCalls: 200,
|
|
/**
|
|
* Days of usage the usage page totals by default, and the most it will
|
|
* total at once.
|
|
*/
|
|
UsageDefaultDays: 30,
|
|
UsageMaxDays: 365,
|
|
/**
|
|
* Models listed per page on the usage page, the busiest first.
|
|
*/
|
|
UsageModelPageSize: 20,
|
|
/**
|
|
* How much of a bot's last message the rail's lists carry, as plain
|
|
* text (`messagePreview`): a row shows one line of it.
|
|
*/
|
|
RailPreviewMaxChars: 160,
|
|
/**
|
|
* A session with this many messages is closed when the user writes
|
|
* again, and the message starts the next one (carrying a summary).
|
|
*/
|
|
BotSessionMaxMessages: 120,
|
|
/**
|
|
* How much of a closed session the bot reads to summarize it, and how
|
|
* long the summary may be.
|
|
*/
|
|
BotSessionSummaryMessages: 80,
|
|
BotSessionSummaryMaxChars: 4000,
|
|
/**
|
|
* The first messages of a session the bot reads to name and summarize
|
|
* it once the first reply is in, and how long its title may be.
|
|
*/
|
|
BotSessionNameMessages: 4,
|
|
BotSessionTitleMaxChars: 80,
|
|
/**
|
|
* Sessions listed per page in a conversation's sessions modal.
|
|
*/
|
|
BotSessionsPageSize: 30,
|
|
/**
|
|
* Worker bots the rail lists, most recently active first, before
|
|
* "See all bots".
|
|
*/
|
|
RailRecentBots: 5,
|
|
/**
|
|
* Workspaces the rail lists, most recently active first, before
|
|
* "See all workspaces".
|
|
*/
|
|
RailRecentWorkspaces: 5,
|
|
/**
|
|
* Stones shown beside "See all bots" and "See all workspaces".
|
|
*/
|
|
RailSeeAllStones: 3,
|
|
/**
|
|
* Recent sessions the rail lists under the open bot, before "All
|
|
* sessions".
|
|
*/
|
|
RailRecentSessions: 5,
|
|
/**
|
|
* Recent sessions a workspace's dashboard shows.
|
|
*/
|
|
WorkspaceActivityItems: 6,
|
|
/**
|
|
* Tool turns a chat reply may take. Long work goes to a task instead.
|
|
* The install may save its own limit (the `bot_reply_max_tool_steps`
|
|
* setting, Settings > General), which wins over this one; a reply
|
|
* reads it through `grabReplyMaxToolSteps`.
|
|
*/
|
|
BotReplyMaxToolSteps: 20,
|
|
/**
|
|
* Messages a chat reply may send while it works (`send_message`):
|
|
* acknowledging something the user wrote meanwhile, a heads-up. Its
|
|
* answer still comes at the end.
|
|
*/
|
|
BotReplyInterimMessagesMax: 3,
|
|
/**
|
|
* The most steps a saved run limit may ask for, for a task run or a
|
|
* chat reply. A typo in the settings page can't turn one run into an
|
|
* hour of tool calls, and a huge limit still ends with a report.
|
|
*/
|
|
BotStepLimitMax: 1000,
|
|
/**
|
|
* Chat attachments: per file, per message, and how much of a
|
|
* document's text a reply reads.
|
|
*/
|
|
BotAttachmentMaxBytes: 20 * 1024 * 1024,
|
|
BotAttachmentMaxFiles: 6,
|
|
BotAttachmentMaxTextChars: 20000,
|
|
/**
|
|
* How much of a document's text is kept on its `media` row. A ceiling
|
|
* on the column itself: without it a 20 MB PDF left 20 MB of text in
|
|
* the database, even though a reply reads at most
|
|
* `BotAttachmentMaxTextChars` of it.
|
|
*/
|
|
BotAttachmentTextStoreMaxChars: 200000,
|
|
/**
|
|
* Only this many of the latest messages with files hand the files
|
|
* themselves to a reply; older ones are named.
|
|
*/
|
|
BotReplyAttachmentMessages: 4,
|
|
/**
|
|
* Longest dictation the composer records before it stops on its own.
|
|
*/
|
|
ComposerVoiceMaxMs: 5 * 60 * 1000,
|
|
/**
|
|
* Most bots or workspaces the composer's mention menu lists at once.
|
|
*/
|
|
ComposerMentionMaxItems: 6,
|
|
/**
|
|
* How long a message's copy button shows a check after it copied the
|
|
* message, before it goes back to the copy icon.
|
|
*/
|
|
CopyConfirmationMs: 1500,
|
|
/**
|
|
* Most of a bot message read aloud; the rest is cut.
|
|
*/
|
|
SpeechMaxChars: 4000,
|
|
/**
|
|
* Bot files: a bot's own directory and a workspace's shared one live
|
|
* under `DATA_DIR` (`DATA_DIR/bots/<id>`, `DATA_DIR/workspaces/<id>`),
|
|
* on the data volume, never on a computer.
|
|
*/
|
|
BotDataDir: "bots",
|
|
WorkspaceDataDir: "workspaces",
|
|
/**
|
|
* The per-owner quota when the General settings page has none saved.
|
|
*/
|
|
BotFileQuotaMb: 1024,
|
|
/**
|
|
* One file a bot writes in one call, and the most of a file a read
|
|
* hands back at once (the rest comes with an offset).
|
|
*/
|
|
BotFileWriteMaxChars: 200_000,
|
|
BotFileReadMaxChars: 40_000,
|
|
BotFileListMaxItems: 200,
|
|
BotFileNameMaxChars: 120,
|
|
BotFilePathMaxChars: 400,
|
|
/**
|
|
* Most folders deep a path may go, so nothing buries a file.
|
|
*/
|
|
BotFilePathMaxDepth: 8,
|
|
/**
|
|
* Most folders deep the files browser opens: a computer's workspace
|
|
* starts four down (`bots/<bot>/users/<user>`) before a bot's own
|
|
* folders begin.
|
|
*/
|
|
StorageBrowserMaxDepth: 16,
|
|
/**
|
|
* The files modal and the bot's file list: one page of them.
|
|
*/
|
|
BotFilesPageSize: 50,
|
|
/**
|
|
* The files browser at `/admin/files`: how many entries one folder
|
|
* shows, and the most of a file it hands back at once.
|
|
*/
|
|
StorageBrowserPageSize: 200,
|
|
StorageBrowserReadMaxBytes: 50 * 1024 * 1024,
|
|
/**
|
|
* The database browser at `/admin/settings/database`: how many records
|
|
* of a table one page shows, how much of a value a cell carries before
|
|
* the rest waits behind its record's modal, and the most of one value
|
|
* that modal shows (a whole media row or job checkpoint is not meant
|
|
* to be rendered).
|
|
*/
|
|
DatabaseBrowserPageSize: 50,
|
|
DatabaseBrowserCellMaxChars: 400,
|
|
DatabaseBrowserValueMaxChars: 20000,
|
|
/**
|
|
* The most words one search matches in the database browser.
|
|
*/
|
|
DatabaseBrowserMaxSearchWords: 8,
|
|
/**
|
|
* The most a bot copies off a computer into its own files in one
|
|
* call, so a folder of raw evidence can't fill the data volume.
|
|
*/
|
|
BotFileImportMaxBytes: 20 * 1024 * 1024,
|
|
/**
|
|
* Ingesting a bot file: how much text one chunk holds, how much of the
|
|
* previous chunk it repeats, and the largest file it reads at all.
|
|
*/
|
|
ChunkTargetChars: 1200,
|
|
ChunkOverlapChars: 200,
|
|
IngestMaxBytes: 20 * 1024 * 1024,
|
|
/**
|
|
* The fixed width of every vector, whatever the embedding model
|
|
* returns: shorter vectors are padded with zeros and longer ones cut,
|
|
* then all are normalized. Changing it needs
|
|
* `bunx bun-sqlite schema --vector` and a full re-ingest.
|
|
*/
|
|
EmbeddingDimensions: 1536,
|
|
/**
|
|
* Texts sent to the embedding model per call, and per run of the
|
|
* ingestion worker.
|
|
*/
|
|
EmbeddingBatchSize: 32,
|
|
EmbeddingMaxInputChars: 8000,
|
|
/**
|
|
* How many chunks a file search returns, and how many more it asks
|
|
* the vector index for before filtering to the run's scopes.
|
|
*/
|
|
RagTopChunks: 8,
|
|
RagOverFetch: 4,
|
|
RagMaxK: 60,
|
|
FileIngestPollMs: 5000,
|
|
FileIngestConcurrency: 2,
|
|
FileIngestWorker: "ingest",
|
|
FileIngestMaxAttempts: 2,
|
|
/**
|
|
* What a speech model reads when a voice is tried in the model settings.
|
|
*/
|
|
VoicePreviewText:
|
|
"Hi there. This is how I'll sound when I read my replies aloud.",
|
|
/**
|
|
* Largest picture a bot or a workspace can have.
|
|
*/
|
|
ProfileImageMaxBytes: 5 * 1024 * 1024,
|
|
/**
|
|
* A user with an open socket seen this recently gets no push: they
|
|
* are already looking at the app.
|
|
*/
|
|
PushPresenceWindowMs: 45_000,
|
|
/**
|
|
* A notification's body is one line, cut here.
|
|
*/
|
|
PushBodyMaxChars: 140,
|
|
/**
|
|
* How long a push service may hold a notification for a device that
|
|
* is offline.
|
|
*/
|
|
PushTtlSeconds: 60 * 60,
|
|
/**
|
|
* Whole-data archives (Settings > Backups): the file name prefix and
|
|
* how many of them are kept, newest first. They live outside
|
|
* `DATA_DIR` (`BACKUP_ARCHIVE_DIR`), never in the database's own
|
|
* `db/.backups` directory, which keeps its bun-sqlite snapshots.
|
|
*/
|
|
DataBackupNamePrefix: "cobble-data-",
|
|
DataBackupsKept: 5,
|
|
/**
|
|
* How often the backups page asks how a whole-data archive or restore
|
|
* is going, and how long it waits for the app to come back after a
|
|
* restore restarted it before it reloads anyway.
|
|
*/
|
|
DataBackupPollMs: 2000,
|
|
DataRestoreWaitMs: 120000,
|
|
/**
|
|
* Responses smaller than this go out uncompressed: the encoding
|
|
* costs more than it saves.
|
|
*/
|
|
CompressMinBytes: 1024,
|
|
/**
|
|
* Brotli quality for page scripts and styles, compressed once per
|
|
* file and kept in memory (`compressResponse`). 11 is about 25 times
|
|
* slower for 10% less; 5 is close to 9's size at half the time.
|
|
*/
|
|
CompressBrotliQuality: 5,
|
|
/**
|
|
* How many compressed page scripts and styles, and how many bytes of
|
|
* them, stay in memory. A rebuild names its files anew, so the oldest
|
|
* go first.
|
|
*/
|
|
CompressCacheMaxFiles: 600,
|
|
CompressCacheMaxBytes: 32 * 1024 * 1024,
|
|
|
|
DefaultIconSize: 16,
|
|
} as const;
|