Files
cobble/src/data/app-data.ts
T
tbenandClaude Opus 5.5 c6ec7d77a2 Add MCP servers and custom tools for bots
Two new settings pages, MCPs and Tools. Super admins define them; super
admins and admins attach them to bots, to workspaces (every bot there),
or to every bot. Bots get them in chat replies and tasks.

- Custom tools: a JSON-schema of arguments plus an HTTP request, a script
  on the bot's computer, or a prompt, templated with {{args.x}} and
  {{env.KEY}}, secrets redacted from results.
- MCP servers: remote (URL and headers) or stdio commands run on the host
  with a setup command and an isolated env, in a per-process pool. Tools
  are listed into a cache and connect on first call.
- Add, edit, access and try open in modals.
- Markdown, JSON and command fields use twui's AceEditor (CodeEditor),
  its scripts loaded on demand.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-19 15:01:39 +01:00

269 lines
9.0 KiB
TypeScript

import { SiteData } from "./site-data";
export const AppData = {
HashCost: 12,
/**
* Shared with twui's `ColorSchemeSelector`, so it must stay `theme`.
*/
ThemeStorageKey: "theme",
/**
* Prefix of the composer's unsent drafts in `localStorage`, one per
* bot and workspace.
*/
ComposerDraftStorageKey: `${SiteData["SiteSlug"]}_composer_draft`,
ServerHealthMessage: "Server Running Well",
AuthKeyCookieName: `${SiteData["SiteSlug"]}_auth_key`,
AuthCSRFCookieName: `${SiteData["SiteSlug"]}_auth_csrf`,
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`,
/**
* A computer's home directory (`ComputerHomeDir` in its container) is
* kept at `DATA_DIR/<ComputerDataDir>/<id>`, owned by the sandbox's
* user. It stays when the computer is deleted.
*/
ComputerDataDir: "computers",
ComputerHomeDir: "/home/gem",
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,
/**
* 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,
/**
* 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,
/**
* 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.
*/
HarnessMaxToolSteps: 30,
/**
* 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,
/**
* `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,
/**
* How much of the conversation a bot sees when it replies.
*/
BotReplyHistoryMessages: 40,
/**
* 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,
/**
* 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: 8,
/**
* Stones shown beside "See all bots".
*/
RailSeeAllStones: 4,
/**
* Recent sessions a workspace's dashboard shows.
*/
WorkspaceActivityItems: 6,
/**
* Tool turns a chat reply may take. Long work goes to a task instead.
*/
BotReplyMaxToolSteps: 8,
/**
* 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,
/**
* Only this many of the latest messages with files hand the files
* themselves to a reply; older ones are named.
*/
BotReplyAttachmentMessages: 4,
/**
* Largest picture a bot or a workspace can have.
*/
ProfileImageMaxBytes: 5 * 1024 * 1024,
} as const;