@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +20 -2
- package/bootstrap.json +22 -0
- package/dist/admin/admin.controller.d.ts +139 -0
- package/dist/admin/admin.controller.js +238 -0
- package/dist/admin/extensions.controller.d.ts +100 -0
- package/dist/admin/extensions.controller.js +226 -0
- package/dist/admin/setup.controller.d.ts +36 -0
- package/dist/admin/setup.controller.js +106 -0
- package/dist/admin/setup.service.d.ts +47 -0
- package/dist/admin/setup.service.js +90 -0
- package/dist/agents/agents.controller.d.ts +205 -0
- package/dist/agents/agents.controller.js +144 -0
- package/dist/agents/agents.service.d.ts +177 -0
- package/dist/agents/agents.service.js +677 -0
- package/dist/agents/definition.d.ts +198 -0
- package/dist/agents/definition.js +152 -0
- package/dist/agents/models.controller.d.ts +13 -0
- package/dist/agents/models.controller.js +31 -0
- package/dist/agents/templates.controller.d.ts +15 -0
- package/dist/agents/templates.controller.js +37 -0
- package/dist/agents/templates.d.ts +83 -0
- package/dist/agents/templates.js +173 -0
- package/dist/catalog/admin-catalog.controller.d.ts +143 -0
- package/dist/catalog/admin-catalog.controller.js +245 -0
- package/dist/catalog/catalog.service.d.ts +430 -0
- package/dist/catalog/catalog.service.js +882 -0
- package/dist/catalog/claude/agents.d.ts +27 -0
- package/dist/catalog/claude/agents.js +270 -0
- package/dist/catalog/claude/commands.d.ts +50 -0
- package/dist/catalog/claude/commands.js +179 -0
- package/dist/catalog/claude/manifest.d.ts +69 -0
- package/dist/catalog/claude/manifest.js +134 -0
- package/dist/catalog/claude/marketplace.d.ts +35 -0
- package/dist/catalog/claude/marketplace.js +194 -0
- package/dist/catalog/claude/mcp.d.ts +33 -0
- package/dist/catalog/claude/mcp.js +226 -0
- package/dist/catalog/claude/report.d.ts +86 -0
- package/dist/catalog/claude/report.js +121 -0
- package/dist/catalog/claude/translate.d.ts +56 -0
- package/dist/catalog/claude/translate.js +857 -0
- package/dist/catalog/cli.d.ts +46 -0
- package/dist/catalog/cli.js +211 -0
- package/dist/catalog/git-source.d.ts +127 -0
- package/dist/catalog/git-source.js +520 -0
- package/dist/catalog/marketplace-fetch.d.ts +99 -0
- package/dist/catalog/marketplace-fetch.js +203 -0
- package/dist/catalog/marketplaces.controller.d.ts +97 -0
- package/dist/catalog/marketplaces.controller.js +197 -0
- package/dist/catalog/marketplaces.service.d.ts +340 -0
- package/dist/catalog/marketplaces.service.js +1217 -0
- package/dist/catalog/org-catalog.controller.d.ts +128 -0
- package/dist/catalog/org-catalog.controller.js +277 -0
- package/dist/catalog/org-catalog.service.d.ts +246 -0
- package/dist/catalog/org-catalog.service.js +625 -0
- package/dist/catalog/plugin-import.d.ts +436 -0
- package/dist/catalog/plugin-import.js +1069 -0
- package/dist/catalog/plugin-install.d.ts +447 -0
- package/dist/catalog/plugin-install.js +1333 -0
- package/dist/catalog/plugin-package.d.ts +143 -0
- package/dist/catalog/plugin-package.js +382 -0
- package/dist/catalog/plugin-upgrade.d.ts +222 -0
- package/dist/catalog/plugin-upgrade.js +1219 -0
- package/dist/catalog/requests.service.d.ts +162 -0
- package/dist/catalog/requests.service.js +504 -0
- package/dist/catalog/schema-path.d.ts +7 -0
- package/dist/catalog/schema-path.js +63 -0
- package/dist/catalog/upgrade-targets.d.ts +59 -0
- package/dist/catalog/upgrade-targets.js +90 -0
- package/dist/catalog/versions.d.ts +31 -0
- package/dist/catalog/versions.js +44 -0
- package/dist/channels/actions.d.ts +37 -0
- package/dist/channels/actions.js +121 -0
- package/dist/channels/cards.d.ts +44 -0
- package/dist/channels/cards.js +156 -0
- package/dist/channels/connections.controller.d.ts +59 -0
- package/dist/channels/connections.controller.js +115 -0
- package/dist/channels/connections.service.d.ts +187 -0
- package/dist/channels/connections.service.js +534 -0
- package/dist/channels/features.d.ts +12 -0
- package/dist/channels/features.js +22 -0
- package/dist/channels/inbound.d.ts +120 -0
- package/dist/channels/inbound.js +332 -0
- package/dist/channels/outbound.d.ts +140 -0
- package/dist/channels/outbound.js +1125 -0
- package/dist/channels/phrases.d.ts +100 -0
- package/dist/channels/phrases.js +81 -0
- package/dist/channels/supervisor.d.ts +182 -0
- package/dist/channels/supervisor.js +625 -0
- package/dist/channels/threads.d.ts +29 -0
- package/dist/channels/threads.js +104 -0
- package/dist/channels/webhook-url.d.ts +16 -0
- package/dist/channels/webhook-url.js +34 -0
- package/dist/channels/webhook.controller.d.ts +19 -0
- package/dist/channels/webhook.controller.js +72 -0
- package/dist/channels/webhook.d.ts +73 -0
- package/dist/channels/webhook.js +274 -0
- package/dist/config/docs.d.ts +9 -0
- package/dist/config/docs.js +85 -0
- package/dist/config/env.d.ts +6 -0
- package/dist/config/env.js +73 -0
- package/dist/config/fields.d.ts +42 -0
- package/dist/config/fields.js +214 -0
- package/dist/config/file-source.d.ts +3 -0
- package/dist/config/file-source.js +31 -0
- package/dist/config/load.d.ts +20 -0
- package/dist/config/load.js +98 -0
- package/dist/config/nacos-source.d.ts +31 -0
- package/dist/config/nacos-source.js +229 -0
- package/dist/config/schema.d.ts +223 -0
- package/dist/config/schema.js +1151 -0
- package/dist/config/sources.d.ts +18 -0
- package/dist/config/sources.js +59 -0
- package/dist/config/types.d.ts +9 -0
- package/dist/config/types.js +7 -0
- package/dist/conversations/artifacts.d.ts +52 -0
- package/dist/conversations/artifacts.js +137 -0
- package/dist/conversations/attachments.controller.d.ts +28 -0
- package/dist/conversations/attachments.controller.js +96 -0
- package/dist/conversations/attachments.service.d.ts +180 -0
- package/dist/conversations/attachments.service.js +578 -0
- package/dist/conversations/conversations.controller.d.ts +288 -0
- package/dist/conversations/conversations.controller.js +607 -0
- package/dist/conversations/conversations.service.d.ts +321 -0
- package/dist/conversations/conversations.service.js +754 -0
- package/dist/conversations/event-log.d.ts +122 -0
- package/dist/conversations/event-log.js +259 -0
- package/dist/conversations/events.d.ts +856 -0
- package/dist/conversations/events.js +639 -0
- package/dist/conversations/files.d.ts +92 -0
- package/dist/conversations/files.js +213 -0
- package/dist/conversations/outputs-read.d.ts +34 -0
- package/dist/conversations/outputs-read.js +37 -0
- package/dist/conversations/queue.d.ts +169 -0
- package/dist/conversations/queue.js +527 -0
- package/dist/conversations/sandbox-status.d.ts +21 -0
- package/dist/conversations/sandbox-status.js +24 -0
- package/dist/conversations/selection.d.ts +46 -0
- package/dist/conversations/selection.js +75 -0
- package/dist/conversations/titles.d.ts +93 -0
- package/dist/conversations/titles.js +422 -0
- package/dist/ctx/bus.d.ts +16 -0
- package/dist/ctx/bus.js +101 -0
- package/dist/ctx/create-ctx.d.ts +109 -0
- package/dist/ctx/create-ctx.js +592 -0
- package/dist/ctx/kv.d.ts +4 -0
- package/dist/ctx/kv.js +31 -0
- package/dist/ctx/lock.d.ts +4 -0
- package/dist/ctx/lock.js +39 -0
- package/dist/ctx/namespace.d.ts +6 -0
- package/dist/ctx/namespace.js +12 -0
- package/dist/ctx/queue.d.ts +25 -0
- package/dist/ctx/queue.js +150 -0
- package/dist/ctx/secrets.d.ts +45 -0
- package/dist/ctx/secrets.js +175 -0
- package/dist/db/kernel-schema.d.ts +1122 -0
- package/dist/db/kernel-schema.js +5 -0
- package/dist/db/migrator.d.ts +28 -0
- package/dist/db/migrator.js +140 -0
- package/dist/db/pool.d.ts +21 -0
- package/dist/db/pool.js +28 -0
- package/dist/db/sql-statements.d.ts +34 -0
- package/dist/db/sql-statements.js +168 -0
- package/dist/errors.d.ts +210 -0
- package/dist/errors.js +212 -0
- package/dist/evals/budget.d.ts +61 -0
- package/dist/evals/budget.js +181 -0
- package/dist/evals/diff.d.ts +55 -0
- package/dist/evals/diff.js +133 -0
- package/dist/evals/judge.d.ts +53 -0
- package/dist/evals/judge.js +149 -0
- package/dist/evals/plan.d.ts +47 -0
- package/dist/evals/plan.js +77 -0
- package/dist/evals/reconstruct.d.ts +137 -0
- package/dist/evals/reconstruct.js +322 -0
- package/dist/evals/recorded-tools.d.ts +54 -0
- package/dist/evals/recorded-tools.js +167 -0
- package/dist/evals/run-replay.d.ts +86 -0
- package/dist/evals/run-replay.js +502 -0
- package/dist/evals/runs.controller.d.ts +100 -0
- package/dist/evals/runs.controller.js +199 -0
- package/dist/evals/runs.service.d.ts +275 -0
- package/dist/evals/runs.service.js +836 -0
- package/dist/evals/sets.controller.d.ts +61 -0
- package/dist/evals/sets.controller.js +183 -0
- package/dist/evals/sets.service.d.ts +128 -0
- package/dist/evals/sets.service.js +558 -0
- package/dist/evals/snapshot.d.ts +76 -0
- package/dist/evals/snapshot.js +207 -0
- package/dist/evals/step-replay.d.ts +113 -0
- package/dist/evals/step-replay.js +181 -0
- package/dist/evals/trajectory.controller.d.ts +41 -0
- package/dist/evals/trajectory.controller.js +88 -0
- package/dist/evals/trajectory.d.ts +144 -0
- package/dist/evals/trajectory.js +338 -0
- package/dist/evals/trajectory.service.d.ts +108 -0
- package/dist/evals/trajectory.service.js +323 -0
- package/dist/evals/worker.d.ts +101 -0
- package/dist/evals/worker.js +789 -0
- package/dist/extensions/admin-ops.d.ts +105 -0
- package/dist/extensions/admin-ops.js +353 -0
- package/dist/extensions/admin-view.d.ts +79 -0
- package/dist/extensions/admin-view.js +327 -0
- package/dist/extensions/approvals.d.ts +119 -0
- package/dist/extensions/approvals.js +205 -0
- package/dist/extensions/blobs.d.ts +45 -0
- package/dist/extensions/blobs.js +160 -0
- package/dist/extensions/bootstrap.d.ts +149 -0
- package/dist/extensions/bootstrap.js +441 -0
- package/dist/extensions/cli.d.ts +61 -0
- package/dist/extensions/cli.js +165 -0
- package/dist/extensions/config-json-schema.d.ts +9 -0
- package/dist/extensions/config-json-schema.js +73 -0
- package/dist/extensions/deployment-config.d.ts +138 -0
- package/dist/extensions/deployment-config.js +394 -0
- package/dist/extensions/enabled.d.ts +31 -0
- package/dist/extensions/enabled.js +55 -0
- package/dist/extensions/hooks.d.ts +161 -0
- package/dist/extensions/hooks.js +425 -0
- package/dist/extensions/host.d.ts +577 -0
- package/dist/extensions/host.js +2071 -0
- package/dist/extensions/inflight.d.ts +69 -0
- package/dist/extensions/inflight.js +277 -0
- package/dist/extensions/installs.d.ts +166 -0
- package/dist/extensions/installs.js +253 -0
- package/dist/extensions/instance.d.ts +167 -0
- package/dist/extensions/instance.js +329 -0
- package/dist/extensions/ledger.d.ts +30 -0
- package/dist/extensions/ledger.js +50 -0
- package/dist/extensions/lifecycle.d.ts +80 -0
- package/dist/extensions/lifecycle.js +152 -0
- package/dist/extensions/migrate-lock.d.ts +51 -0
- package/dist/extensions/migrate-lock.js +100 -0
- package/dist/extensions/org-config.controller.d.ts +24 -0
- package/dist/extensions/org-config.controller.js +59 -0
- package/dist/extensions/org-config.d.ts +169 -0
- package/dist/extensions/org-config.js +520 -0
- package/dist/extensions/package.d.ts +115 -0
- package/dist/extensions/package.js +246 -0
- package/dist/extensions/permission-set.d.ts +117 -0
- package/dist/extensions/permission-set.js +184 -0
- package/dist/extensions/permission-view.d.ts +194 -0
- package/dist/extensions/permission-view.js +284 -0
- package/dist/extensions/registry.d.ts +24 -0
- package/dist/extensions/registry.js +56 -0
- package/dist/extensions/resolve.d.ts +12 -0
- package/dist/extensions/resolve.js +71 -0
- package/dist/extensions/sources.d.ts +69 -0
- package/dist/extensions/sources.js +120 -0
- package/dist/extensions/sync.d.ts +40 -0
- package/dist/extensions/sync.js +242 -0
- package/dist/files/previewers.controller.d.ts +46 -0
- package/dist/files/previewers.controller.js +105 -0
- package/dist/files/previewers.d.ts +100 -0
- package/dist/files/previewers.js +250 -0
- package/dist/http/api.module.d.ts +114 -0
- package/dist/http/api.module.js +448 -0
- package/dist/http/app.d.ts +77 -0
- package/dist/http/app.js +170 -0
- package/dist/http/error.filter.d.ts +21 -0
- package/dist/http/error.filter.js +85 -0
- package/dist/http/gateway.module.d.ts +15 -0
- package/dist/http/gateway.module.js +13 -0
- package/dist/http/health.controller.d.ts +26 -0
- package/dist/http/health.controller.js +79 -0
- package/dist/http/nest-logger.d.ts +20 -0
- package/dist/http/nest-logger.js +28 -0
- package/dist/http/plugin-dispatch.d.ts +68 -0
- package/dist/http/plugin-dispatch.js +200 -0
- package/dist/http/tokens.d.ts +131 -0
- package/dist/http/tokens.js +131 -0
- package/dist/http/zod.pipe.d.ts +8 -0
- package/dist/http/zod.pipe.js +14 -0
- package/dist/identity/accounts.d.ts +93 -0
- package/dist/identity/accounts.js +367 -0
- package/dist/identity/api-tokens.d.ts +73 -0
- package/dist/identity/api-tokens.js +197 -0
- package/dist/identity/audit.d.ts +23 -0
- package/dist/identity/audit.js +41 -0
- package/dist/identity/auth.controller.d.ts +40 -0
- package/dist/identity/auth.controller.js +130 -0
- package/dist/identity/auth.guard.d.ts +41 -0
- package/dist/identity/auth.guard.js +162 -0
- package/dist/identity/binding.d.ts +47 -0
- package/dist/identity/binding.js +84 -0
- package/dist/identity/cookies.d.ts +16 -0
- package/dist/identity/cookies.js +32 -0
- package/dist/identity/credential-check.d.ts +17 -0
- package/dist/identity/credential-check.js +24 -0
- package/dist/identity/enterprise-admin.d.ts +14 -0
- package/dist/identity/enterprise-admin.js +27 -0
- package/dist/identity/external.d.ts +106 -0
- package/dist/identity/external.js +337 -0
- package/dist/identity/hash.d.ts +2 -0
- package/dist/identity/hash.js +3 -0
- package/dist/identity/login.d.ts +6 -0
- package/dist/identity/login.js +20 -0
- package/dist/identity/me.controller.d.ts +61 -0
- package/dist/identity/me.controller.js +159 -0
- package/dist/identity/passwords.d.ts +6 -0
- package/dist/identity/passwords.js +37 -0
- package/dist/identity/principal.d.ts +56 -0
- package/dist/identity/principal.js +38 -0
- package/dist/identity/rate-limit.d.ts +55 -0
- package/dist/identity/rate-limit.js +121 -0
- package/dist/identity/sessions.d.ts +84 -0
- package/dist/identity/sessions.js +306 -0
- package/dist/identity/settings.d.ts +121 -0
- package/dist/identity/settings.js +248 -0
- package/dist/identity/sso.controller.d.ts +59 -0
- package/dist/identity/sso.controller.js +192 -0
- package/dist/identity/sso.d.ts +83 -0
- package/dist/identity/sso.js +202 -0
- package/dist/inbox/inbox.service.d.ts +43 -0
- package/dist/inbox/inbox.service.js +57 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.js +65 -0
- package/dist/kernel.d.ts +256 -0
- package/dist/kernel.js +1326 -0
- package/dist/log.d.ts +48 -0
- package/dist/log.js +229 -0
- package/dist/models/prices.d.ts +53 -0
- package/dist/models/prices.js +121 -0
- package/dist/models/purposes.controller.d.ts +19 -0
- package/dist/models/purposes.controller.js +56 -0
- package/dist/models/purposes.d.ts +140 -0
- package/dist/models/purposes.js +267 -0
- package/dist/net/proxy.d.ts +44 -0
- package/dist/net/proxy.js +162 -0
- package/dist/net/public-address.d.ts +60 -0
- package/dist/net/public-address.js +271 -0
- package/dist/net/safe-fetch.d.ts +38 -0
- package/dist/net/safe-fetch.js +140 -0
- package/dist/orgs/directory-sync.controller.d.ts +14 -0
- package/dist/orgs/directory-sync.controller.js +40 -0
- package/dist/orgs/directory-sync.d.ts +166 -0
- package/dist/orgs/directory-sync.js +558 -0
- package/dist/orgs/invitations.controller.d.ts +58 -0
- package/dist/orgs/invitations.controller.js +137 -0
- package/dist/orgs/invitations.service.d.ts +80 -0
- package/dist/orgs/invitations.service.js +217 -0
- package/dist/orgs/members.service.d.ts +63 -0
- package/dist/orgs/members.service.js +234 -0
- package/dist/orgs/offboarding.d.ts +141 -0
- package/dist/orgs/offboarding.js +398 -0
- package/dist/orgs/org-lock.d.ts +32 -0
- package/dist/orgs/org-lock.js +46 -0
- package/dist/orgs/org.guard.d.ts +35 -0
- package/dist/orgs/org.guard.js +95 -0
- package/dist/orgs/orgs.controller.d.ts +78 -0
- package/dist/orgs/orgs.controller.js +192 -0
- package/dist/orgs/orgs.service.d.ts +61 -0
- package/dist/orgs/orgs.service.js +209 -0
- package/dist/orgs/roles.d.ts +13 -0
- package/dist/orgs/roles.js +58 -0
- package/dist/orgs/settings.controller.d.ts +20 -0
- package/dist/orgs/settings.controller.js +53 -0
- package/dist/orgs/settings.service.d.ts +120 -0
- package/dist/orgs/settings.service.js +178 -0
- package/dist/packages/npm.d.ts +50 -0
- package/dist/packages/npm.js +218 -0
- package/dist/packages/provenance.d.ts +47 -0
- package/dist/packages/provenance.js +147 -0
- package/dist/packages/tgz.d.ts +76 -0
- package/dist/packages/tgz.js +225 -0
- package/dist/runtime/abort.d.ts +32 -0
- package/dist/runtime/abort.js +71 -0
- package/dist/runtime/checkpointer.d.ts +32 -0
- package/dist/runtime/checkpointer.js +243 -0
- package/dist/runtime/context/build.d.ts +254 -0
- package/dist/runtime/context/build.js +693 -0
- package/dist/runtime/context/claude-tools.d.ts +11 -0
- package/dist/runtime/context/claude-tools.js +24 -0
- package/dist/runtime/context/compaction.d.ts +26 -0
- package/dist/runtime/context/compaction.js +195 -0
- package/dist/runtime/context/pairing.d.ts +11 -0
- package/dist/runtime/context/pairing.js +82 -0
- package/dist/runtime/context/reminders.d.ts +5 -0
- package/dist/runtime/context/reminders.js +11 -0
- package/dist/runtime/context/skills.d.ts +105 -0
- package/dist/runtime/context/skills.js +283 -0
- package/dist/runtime/context/tokens.d.ts +19 -0
- package/dist/runtime/context/tokens.js +104 -0
- package/dist/runtime/conversation-lock.d.ts +40 -0
- package/dist/runtime/conversation-lock.js +97 -0
- package/dist/runtime/hook-calls.d.ts +84 -0
- package/dist/runtime/hook-calls.js +136 -0
- package/dist/runtime/langgraph-loop.d.ts +52 -0
- package/dist/runtime/langgraph-loop.js +247 -0
- package/dist/runtime/loop.d.ts +93 -0
- package/dist/runtime/loop.js +7 -0
- package/dist/runtime/maintenance.d.ts +80 -0
- package/dist/runtime/maintenance.js +147 -0
- package/dist/runtime/media-cache.d.ts +21 -0
- package/dist/runtime/media-cache.js +51 -0
- package/dist/runtime/model-call.d.ts +176 -0
- package/dist/runtime/model-call.js +1049 -0
- package/dist/runtime/providers.d.ts +86 -0
- package/dist/runtime/providers.js +224 -0
- package/dist/runtime/quota.d.ts +29 -0
- package/dist/runtime/quota.js +70 -0
- package/dist/runtime/run-finish.d.ts +45 -0
- package/dist/runtime/run-finish.js +69 -0
- package/dist/runtime/run-queue.d.ts +121 -0
- package/dist/runtime/run-queue.js +493 -0
- package/dist/runtime/run-worker.d.ts +138 -0
- package/dist/runtime/run-worker.js +805 -0
- package/dist/runtime/stream.controller.d.ts +34 -0
- package/dist/runtime/stream.controller.js +122 -0
- package/dist/runtime/stream.d.ts +63 -0
- package/dist/runtime/stream.js +262 -0
- package/dist/runtime/subagents/child.d.ts +80 -0
- package/dist/runtime/subagents/child.js +225 -0
- package/dist/runtime/subagents/definition.d.ts +103 -0
- package/dist/runtime/subagents/definition.js +392 -0
- package/dist/runtime/subagents/dispatch.d.ts +69 -0
- package/dist/runtime/subagents/dispatch.js +502 -0
- package/dist/runtime/subagents/limits.d.ts +23 -0
- package/dist/runtime/subagents/limits.js +34 -0
- package/dist/runtime/subagents/org-agents.d.ts +50 -0
- package/dist/runtime/subagents/org-agents.js +70 -0
- package/dist/runtime/subagents/preamble.d.ts +7 -0
- package/dist/runtime/subagents/preamble.js +11 -0
- package/dist/runtime/subagents/progress.d.ts +26 -0
- package/dist/runtime/subagents/progress.js +36 -0
- package/dist/runtime/subagents/roster.d.ts +55 -0
- package/dist/runtime/subagents/roster.js +111 -0
- package/dist/runtime/subagents/skill-fork.d.ts +123 -0
- package/dist/runtime/subagents/skill-fork.js +259 -0
- package/dist/runtime/usage-report.d.ts +163 -0
- package/dist/runtime/usage-report.js +550 -0
- package/dist/runtime/waits.d.ts +233 -0
- package/dist/runtime/waits.js +883 -0
- package/dist/sandbox/leases.d.ts +169 -0
- package/dist/sandbox/leases.js +515 -0
- package/dist/sandbox/lifecycle.d.ts +21 -0
- package/dist/sandbox/lifecycle.js +68 -0
- package/dist/sandbox/sandbox.service.d.ts +249 -0
- package/dist/sandbox/sandbox.service.js +908 -0
- package/dist/skills/catalog.d.ts +149 -0
- package/dist/skills/catalog.js +405 -0
- package/dist/skills/changes.controller.d.ts +56 -0
- package/dist/skills/changes.controller.js +136 -0
- package/dist/skills/changes.service.d.ts +175 -0
- package/dist/skills/changes.service.js +805 -0
- package/dist/skills/invocable.controller.d.ts +23 -0
- package/dist/skills/invocable.controller.js +50 -0
- package/dist/skills/invocation-keys.d.ts +23 -0
- package/dist/skills/invocation-keys.js +44 -0
- package/dist/skills/invoke.d.ts +135 -0
- package/dist/skills/invoke.js +286 -0
- package/dist/skills/package.d.ts +87 -0
- package/dist/skills/package.js +227 -0
- package/dist/skills/skills.controller.d.ts +40 -0
- package/dist/skills/skills.controller.js +110 -0
- package/dist/skills/skills.service.d.ts +192 -0
- package/dist/skills/skills.service.js +567 -0
- package/dist/storage/prefix.d.ts +36 -0
- package/dist/storage/prefix.js +104 -0
- package/dist/storage/purge.d.ts +27 -0
- package/dist/storage/purge.js +75 -0
- package/dist/storage/storage.service.d.ts +44 -0
- package/dist/storage/storage.service.js +145 -0
- package/dist/text.d.ts +13 -0
- package/dist/text.js +13 -0
- package/dist/tools/approvals.controller.d.ts +53 -0
- package/dist/tools/approvals.controller.js +128 -0
- package/dist/tools/approvals.service.d.ts +172 -0
- package/dist/tools/approvals.service.js +568 -0
- package/dist/tools/breaker.d.ts +28 -0
- package/dist/tools/breaker.js +72 -0
- package/dist/tools/builtins/agent.d.ts +81 -0
- package/dist/tools/builtins/agent.js +223 -0
- package/dist/tools/builtins/ask-user.d.ts +28 -0
- package/dist/tools/builtins/ask-user.js +139 -0
- package/dist/tools/builtins/read-tool-output.d.ts +18 -0
- package/dist/tools/builtins/read-tool-output.js +108 -0
- package/dist/tools/builtins/sandbox/bash.d.ts +16 -0
- package/dist/tools/builtins/sandbox/bash.js +137 -0
- package/dist/tools/builtins/sandbox/common.d.ts +114 -0
- package/dist/tools/builtins/sandbox/common.js +304 -0
- package/dist/tools/builtins/sandbox/deliver.d.ts +5 -0
- package/dist/tools/builtins/sandbox/deliver.js +180 -0
- package/dist/tools/builtins/sandbox/edit.d.ts +4 -0
- package/dist/tools/builtins/sandbox/edit.js +98 -0
- package/dist/tools/builtins/sandbox/glob-match.d.ts +25 -0
- package/dist/tools/builtins/sandbox/glob-match.js +240 -0
- package/dist/tools/builtins/sandbox/glob.d.ts +4 -0
- package/dist/tools/builtins/sandbox/glob.js +104 -0
- package/dist/tools/builtins/sandbox/grep.d.ts +9 -0
- package/dist/tools/builtins/sandbox/grep.js +133 -0
- package/dist/tools/builtins/sandbox/index.d.ts +12 -0
- package/dist/tools/builtins/sandbox/index.js +27 -0
- package/dist/tools/builtins/sandbox/names.d.ts +7 -0
- package/dist/tools/builtins/sandbox/names.js +20 -0
- package/dist/tools/builtins/sandbox/read.d.ts +8 -0
- package/dist/tools/builtins/sandbox/read.js +121 -0
- package/dist/tools/builtins/sandbox/write.d.ts +4 -0
- package/dist/tools/builtins/sandbox/write.js +88 -0
- package/dist/tools/builtins/skill-load.d.ts +53 -0
- package/dist/tools/builtins/skill-load.js +446 -0
- package/dist/tools/builtins/skill-write.d.ts +59 -0
- package/dist/tools/builtins/skill-write.js +244 -0
- package/dist/tools/builtins/tool-search.d.ts +31 -0
- package/dist/tools/builtins/tool-search.js +171 -0
- package/dist/tools/connector-content.controller.d.ts +34 -0
- package/dist/tools/connector-content.controller.js +78 -0
- package/dist/tools/connector-content.d.ts +104 -0
- package/dist/tools/connector-content.js +267 -0
- package/dist/tools/connectors.controller.d.ts +210 -0
- package/dist/tools/connectors.controller.js +234 -0
- package/dist/tools/connectors.service.d.ts +303 -0
- package/dist/tools/connectors.service.js +1102 -0
- package/dist/tools/credentials.d.ts +139 -0
- package/dist/tools/credentials.js +351 -0
- package/dist/tools/drift.d.ts +141 -0
- package/dist/tools/drift.js +539 -0
- package/dist/tools/elicitation.d.ts +81 -0
- package/dist/tools/elicitation.js +266 -0
- package/dist/tools/endpoint.d.ts +18 -0
- package/dist/tools/endpoint.js +115 -0
- package/dist/tools/info.d.ts +67 -0
- package/dist/tools/info.js +113 -0
- package/dist/tools/naming.d.ts +27 -0
- package/dist/tools/naming.js +47 -0
- package/dist/tools/oauth/discovery.d.ts +65 -0
- package/dist/tools/oauth/discovery.js +307 -0
- package/dist/tools/oauth/flow.d.ts +63 -0
- package/dist/tools/oauth/flow.js +237 -0
- package/dist/tools/oauth/oauth.controller.d.ts +31 -0
- package/dist/tools/oauth/oauth.controller.js +95 -0
- package/dist/tools/oauth/tokens.d.ts +111 -0
- package/dist/tools/oauth/tokens.js +258 -0
- package/dist/tools/outputs.d.ts +61 -0
- package/dist/tools/outputs.js +156 -0
- package/dist/tools/pipeline.d.ts +322 -0
- package/dist/tools/pipeline.js +1236 -0
- package/dist/tools/policy.d.ts +60 -0
- package/dist/tools/policy.js +236 -0
- package/dist/tools/questions.controller.d.ts +24 -0
- package/dist/tools/questions.controller.js +58 -0
- package/dist/tools/questions.service.d.ts +103 -0
- package/dist/tools/questions.service.js +295 -0
- package/dist/tools/redact.d.ts +20 -0
- package/dist/tools/redact.js +60 -0
- package/dist/tools/registry.d.ts +246 -0
- package/dist/tools/registry.js +481 -0
- package/dist/tools/resources.d.ts +16 -0
- package/dist/tools/resources.js +76 -0
- package/dist/tools/specs.d.ts +14 -0
- package/dist/tools/specs.js +31 -0
- package/dist/tools/validate.d.ts +20 -0
- package/dist/tools/validate.js +183 -0
- package/dist/tools/view.d.ts +43 -0
- package/dist/tools/view.js +225 -0
- package/dist/ui/embed-token.d.ts +31 -0
- package/dist/ui/embed-token.js +132 -0
- package/dist/ui/registry.d.ts +58 -0
- package/dist/ui/registry.js +90 -0
- package/dist/ui/ui-stream.d.ts +37 -0
- package/dist/ui/ui-stream.js +162 -0
- package/dist/ui/views.controller.d.ts +81 -0
- package/dist/ui/views.controller.js +261 -0
- package/dist/ui/views.d.ts +155 -0
- package/dist/ui/views.js +306 -0
- package/dist/version.d.ts +5 -0
- package/dist/version.js +6 -0
- package/package.json +67 -3
- package/src/migrations/0001_init.sql +8 -0
- package/src/migrations/0002_secrets.sql +8 -0
- package/src/migrations/0003_identity.sql +117 -0
- package/src/migrations/0004_plugin_org_config_nullable.sql +3 -0
- package/src/migrations/0005_agents.sql +27 -0
- package/src/migrations/0006_conversations.sql +37 -0
- package/src/migrations/0007_checkpoints.sql +26 -0
- package/src/migrations/0008_runs_trigger_seq.sql +3 -0
- package/src/migrations/0009_runs_active_unique.sql +4 -0
- package/src/migrations/0010_tools.sql +125 -0
- package/src/migrations/0011_approvals_spec.sql +10 -0
- package/src/migrations/0012_run_waits.sql +24 -0
- package/src/migrations/0013_app_tools_source.sql +4 -0
- package/src/migrations/0014_tool_specs.sql +8 -0
- package/src/migrations/0015_tool_drift.sql +20 -0
- package/src/migrations/0016_plugin_permissions.sql +11 -0
- package/src/migrations/0017_identity_sources.sql +6 -0
- package/src/migrations/0018_channels.sql +74 -0
- package/src/migrations/0019_identity_trust.sql +17 -0
- package/src/migrations/0020_channel_card_lookup.sql +10 -0
- package/src/migrations/0021_org_storage_purge.sql +9 -0
- package/src/migrations/0022_attachments.sql +29 -0
- package/src/migrations/0023_sandboxes.sql +37 -0
- package/src/migrations/0024_skills.sql +46 -0
- package/src/migrations/0025_skills_catalog_idx.sql +6 -0
- package/src/migrations/0026_skill_changes.sql +34 -0
- package/src/migrations/0027_model_prices.sql +18 -0
- package/src/migrations/0028_evals.sql +105 -0
- package/src/migrations/0029_model_purposes.sql +18 -0
- package/src/migrations/0030_plugin_installs.sql +73 -0
- package/src/migrations/0031_plugin_snapshot_source.sql +6 -0
- package/src/migrations/0032_plugin_deployment_configs.sql +10 -0
- package/src/migrations/0033_rename_apps_to_connectors.sql +25 -0
- package/src/migrations/0034_directory.sql +49 -0
- package/src/migrations/0035_catalogs.sql +40 -0
- package/src/migrations/0036_app_import_staging.sql +17 -0
- package/src/migrations/0037_directory_installs.sql +92 -0
- package/src/migrations/0038_channel_inbound_mode.sql +6 -0
- package/src/migrations/0039_channel_card_pending.sql +8 -0
- package/src/migrations/0040_usage_report_sweep.sql +10 -0
- package/src/migrations/0041_rename_plugins_to_extensions.sql +38 -0
- package/src/migrations/0042_rename_directory_to_catalog.sql +80 -0
- package/src/migrations/0043_rename_app_installs_to_plugin_installs.sql +20 -0
- package/src/migrations/0044_catalog_one_kind.sql +90 -0
- package/src/migrations/0045_plugin_dependencies.sql +9 -0
- package/src/migrations/0046_git_sources.sql +25 -0
- package/src/migrations/0047_marketplace_entry_heads.sql +7 -0
- package/src/migrations/0048_marketplace_entry_trees.sql +8 -0
- package/src/migrations/0049_plugin_upgrades.sql +37 -0
- package/src/migrations/0050_bootstrap.sql +53 -0
- package/src/migrations/0051_claude_compat.sql +26 -0
- package/src/migrations/0052_conversations_account_agent_idx.sql +5 -0
- package/src/migrations/0053_subagents.sql +73 -0
- package/src/migrations/0054_subagent_wait_expiry.sql +7 -0
- package/src/migrations/0055_subagent_parent_indexes.sql +10 -0
- package/src/migrations/0056_approval_reason.sql +3 -0
- package/src/migrations/0057_conversation_titles.sql +11 -0
- package/src/migrations/0058_conversation_selection.sql +4 -0
- package/src/migrations/0059_conversation_queue.sql +22 -0
- package/src/migrations/0060_file_previewers.sql +10 -0
- package/src/migrations/0061_queue_selection.sql +5 -0
- package/src/migrations/0062_queued_skill.sql +8 -0
|
@@ -0,0 +1,1151 @@
|
|
|
1
|
+
import { isIP } from "node:net";
|
|
2
|
+
import { DOCUMENT_MEDIA_TYPES, IMAGE_MEDIA_TYPES, validateAllowHost, } from "@capybara-hq/plugin-sdk";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
import { LOG_LEVELS } from "../log.js";
|
|
5
|
+
import { noProxyEntryProblem, proxyUrlProblem } from "../net/proxy.js";
|
|
6
|
+
import { privateHostEntryProblem } from "../net/public-address.js";
|
|
7
|
+
/**
|
|
8
|
+
* 构造给 Zod 4 `.meta()` 使用的字段元信息。
|
|
9
|
+
* 用法:`z.string().meta(meta({ secret: true, description: "..." }))`。
|
|
10
|
+
*/
|
|
11
|
+
export function meta(opts) {
|
|
12
|
+
return { ...opts };
|
|
13
|
+
}
|
|
14
|
+
/** 校验 base64 主密钥解码后恰为 32 字节。 */
|
|
15
|
+
function isValidMasterKey(value) {
|
|
16
|
+
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(value))
|
|
17
|
+
return false;
|
|
18
|
+
return Buffer.from(value, "base64").length === 32;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 受信任身份源的一项:完整的身份源键 `<插件名>:<租户 id>`(Ruling A19,信任按租户)。
|
|
22
|
+
* 插件名同清单规则(不能是 `local`),租户 id 非空、不含空白;与 identity/external.ts 的身份源键规则一致。
|
|
23
|
+
*/
|
|
24
|
+
const TRUSTED_SOURCE_RE = /^(?!local:)[a-z0-9][a-z0-9._-]{0,213}:\S{1,256}$/;
|
|
25
|
+
/** `runtime.maxRunSeconds` 的默认值。 */
|
|
26
|
+
export const DEFAULT_MAX_RUN_SECONDS = 900;
|
|
27
|
+
/** `sandbox.limits.maxCommandSeconds` 的默认值。 */
|
|
28
|
+
export const DEFAULT_MAX_COMMAND_SECONDS = 7200;
|
|
29
|
+
/** access token 寿命上限(秒);会话吊销标记的 TTL 按它计算,与实例当前配置无关。 */
|
|
30
|
+
export const ACCESS_TOKEN_TTL_MAX_SECONDS = 3600;
|
|
31
|
+
/** `attachments.requestMediaBytes` 的上限(24 MiB):base64 后约 32 MiB,是常见供应商的请求上限。 */
|
|
32
|
+
export const REQUEST_MEDIA_BYTES_MAX = 25_165_824;
|
|
33
|
+
/**
|
|
34
|
+
* 沙箱出站白名单的默认值(`sandbox.limits.allowHosts`):常用的包仓库与源码托管(git clone、归档下载、
|
|
35
|
+
* raw 文件、release 附件)。不预置 `deb.debian.org`:沙箱用户是 uid 1000、没有 sudo,装不了 apt 包,
|
|
36
|
+
* 放行它只多一个出口;需要系统包的部署把它们装进镜像。组织可以替换这份清单(`sandboxEgress`,Ruling M19)。
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_SANDBOX_ALLOW_HOSTS = [
|
|
39
|
+
"registry.npmjs.org",
|
|
40
|
+
"pypi.org",
|
|
41
|
+
"files.pythonhosted.org",
|
|
42
|
+
"github.com",
|
|
43
|
+
"codeload.github.com",
|
|
44
|
+
"raw.githubusercontent.com",
|
|
45
|
+
"objects.githubusercontent.com",
|
|
46
|
+
"release-assets.githubusercontent.com",
|
|
47
|
+
];
|
|
48
|
+
/** `packages.maxBytes` 的默认值(插件包 tgz 的大小上限);`check:plugin-pack` 用同一个值。 */
|
|
49
|
+
export const PACKAGES_MAX_BYTES_DEFAULT = 52_428_800;
|
|
50
|
+
/**
|
|
51
|
+
* The default of `marketplaces.official.url`: the official plugins repository, a git marketplace
|
|
52
|
+
* (spec §5.5). `marketplaces.official.enabled` is on by default; offline deployments and tests turn
|
|
53
|
+
* it off.
|
|
54
|
+
*/
|
|
55
|
+
export const MARKETPLACE_OFFICIAL_URL_DEFAULT = "https://github.com/capybara-hq/plugins.git";
|
|
56
|
+
/**
|
|
57
|
+
* Whether a marketplace URL names a git repository: its path ends in `.git` (the rule of the
|
|
58
|
+
* catalog's `marketplaceForm` for a full URL; the `owner/repo` shorthand is not a URL and cannot be
|
|
59
|
+
* configured here).
|
|
60
|
+
*/
|
|
61
|
+
const isGitMarketplaceUrl = (url) => {
|
|
62
|
+
try {
|
|
63
|
+
return /\.git\/?$/.test(new URL(url).pathname);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
/** 每个清单来源最多的镜像数。 */
|
|
70
|
+
export const MARKETPLACE_MAX_MIRRORS = 5;
|
|
71
|
+
const masterKey = z
|
|
72
|
+
.string()
|
|
73
|
+
.refine(isValidMasterKey, { message: "must be base64 that decodes to exactly 32 bytes" });
|
|
74
|
+
const HOSTNAME_RE = /^[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?)*$/i;
|
|
75
|
+
/**
|
|
76
|
+
* Why a `marketplaces.allowedHosts` entry is refused, or undefined: a hostname or an IP address
|
|
77
|
+
* (IPv6 without brackets), never a port, scheme or path (entries are compared with the URL's
|
|
78
|
+
* hostname only).
|
|
79
|
+
*/
|
|
80
|
+
export function allowedHostProblem(entry) {
|
|
81
|
+
if (isIP(entry) !== 0)
|
|
82
|
+
return undefined;
|
|
83
|
+
if (entry.startsWith("[")) {
|
|
84
|
+
return `"${entry}": write an IPv6 address without brackets (e.g. ::1)`;
|
|
85
|
+
}
|
|
86
|
+
if (/[/:]/.test(entry)) {
|
|
87
|
+
return `"${entry}": write only the host name, without a scheme, port or path (ports are not compared)`;
|
|
88
|
+
}
|
|
89
|
+
if (!HOSTNAME_RE.test(entry))
|
|
90
|
+
return `"${entry}" is not a hostname or an IP address`;
|
|
91
|
+
return undefined;
|
|
92
|
+
}
|
|
93
|
+
/** proxy-addr's named ranges, which Fastify's trustProxy also accepts. */
|
|
94
|
+
const TRUST_PROXY_NAMES = new Set(["loopback", "linklocal", "uniquelocal"]);
|
|
95
|
+
/**
|
|
96
|
+
* The IPv4 address carried by an IPv4-mapped IPv6 address (`::ffff:0:0/96`) in any spelling
|
|
97
|
+
* (`::ffff:10.0.0.1`, `::ffff:a00:1`, `0:0:0:0:0:ffff:10.0.0.1`), else undefined. Parsed, not matched
|
|
98
|
+
* as text: proxy-addr unwraps every spelling, so a regex on one spelling lets the others through.
|
|
99
|
+
*/
|
|
100
|
+
function mappedIpv4(addr) {
|
|
101
|
+
if (isIP(addr) !== 6)
|
|
102
|
+
return undefined;
|
|
103
|
+
let s = addr.toLowerCase().split("%")[0] ?? "";
|
|
104
|
+
const dotted = /^(.*:)(\d+)\.(\d+)\.(\d+)\.(\d+)$/.exec(s);
|
|
105
|
+
if (dotted !== null) {
|
|
106
|
+
const [a = 0, b = 0, c = 0, d = 0] = dotted.slice(2).map(Number);
|
|
107
|
+
s = `${dotted[1]}${(a * 256 + b).toString(16)}:${(c * 256 + d).toString(16)}`;
|
|
108
|
+
}
|
|
109
|
+
const [head = "", tail] = s.split("::");
|
|
110
|
+
const h = head === "" ? [] : head.split(":");
|
|
111
|
+
const t = tail === undefined || tail === "" ? [] : tail.split(":");
|
|
112
|
+
const words = tail === undefined ? h : [...h, ...Array(8 - h.length - t.length).fill("0"), ...t];
|
|
113
|
+
if (words.length !== 8)
|
|
114
|
+
return undefined;
|
|
115
|
+
const n = words.map((w) => Number.parseInt(w, 16));
|
|
116
|
+
if (n.slice(0, 5).some((x) => x !== 0) || n[5] !== 0xffff)
|
|
117
|
+
return undefined;
|
|
118
|
+
const [hi = 0, lo = 0] = n.slice(6);
|
|
119
|
+
return [hi >> 8, hi & 255, lo >> 8, lo & 255].join(".");
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Why an `http.trustProxy` list entry is refused, or undefined when it is an IP, a CIDR or a named
|
|
123
|
+
* range. A /0 prefix is refused: it trusts every address, so any client could forge the header.
|
|
124
|
+
*/
|
|
125
|
+
export function trustProxyEntryProblem(entry) {
|
|
126
|
+
if (TRUST_PROXY_NAMES.has(entry))
|
|
127
|
+
return undefined;
|
|
128
|
+
const [addr = "", range, extra] = entry.split("/");
|
|
129
|
+
const family = isIP(addr);
|
|
130
|
+
if (family === 0 || extra !== undefined)
|
|
131
|
+
return `"${entry}" is not an IP address or CIDR`;
|
|
132
|
+
if (range === undefined)
|
|
133
|
+
return undefined;
|
|
134
|
+
let bits;
|
|
135
|
+
if (/^\d+$/.test(range)) {
|
|
136
|
+
bits = Number(range);
|
|
137
|
+
}
|
|
138
|
+
else if (family === 4 && isIP(range) === 4) {
|
|
139
|
+
// A dotted netmask (10.0.0.0/255.0.0.0), as proxy-addr accepts: it must be contiguous.
|
|
140
|
+
const mask = range.split(".").reduce((n, o) => n * 256 + Number(o), 0);
|
|
141
|
+
const ones = mask.toString(2).replace(/^0+/, "");
|
|
142
|
+
if (mask !== 0 && (ones.length !== 32 || /01/.test(ones))) {
|
|
143
|
+
return `"${entry}" has a non-contiguous netmask`;
|
|
144
|
+
}
|
|
145
|
+
bits = mask === 0 ? 0 : (ones.match(/1/g) ?? []).length;
|
|
146
|
+
}
|
|
147
|
+
else {
|
|
148
|
+
return `"${entry}" is not an IP address or CIDR`;
|
|
149
|
+
}
|
|
150
|
+
if (bits > (family === 6 ? 128 : 32))
|
|
151
|
+
return `"${entry}" has an out-of-range prefix`;
|
|
152
|
+
// proxy-addr turns an IPv4-mapped IPv6 range (::ffff:a.b.c.d/N, any spelling) into the IPv4
|
|
153
|
+
// range /N-96.
|
|
154
|
+
const mapped = mappedIpv4(addr) !== undefined;
|
|
155
|
+
if (bits === 0 || (mapped && bits === 96)) {
|
|
156
|
+
return `"${entry}" trusts every address; list the proxies' own addresses or CIDRs`;
|
|
157
|
+
}
|
|
158
|
+
// Between /1 and /95 a mapped prefix has no IPv4 equivalent.
|
|
159
|
+
if (mapped && bits < 96)
|
|
160
|
+
return `"${entry}" has an out-of-range prefix`;
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
export const KernelConfigSchema = z.object({
|
|
164
|
+
db: z
|
|
165
|
+
.object({
|
|
166
|
+
url: z
|
|
167
|
+
.string()
|
|
168
|
+
.min(1)
|
|
169
|
+
.meta(meta({ secret: true, description: "PostgreSQL connection URL" })),
|
|
170
|
+
poolMax: z
|
|
171
|
+
.number()
|
|
172
|
+
.int()
|
|
173
|
+
.positive()
|
|
174
|
+
.default(10)
|
|
175
|
+
.meta(meta({ description: "Maximum PostgreSQL pool size" })),
|
|
176
|
+
connectTimeoutMs: z
|
|
177
|
+
.number()
|
|
178
|
+
.int()
|
|
179
|
+
.positive()
|
|
180
|
+
.default(5000)
|
|
181
|
+
.meta(meta({ description: "PostgreSQL connect timeout in milliseconds" })),
|
|
182
|
+
})
|
|
183
|
+
.prefault({}),
|
|
184
|
+
redis: z
|
|
185
|
+
.object({
|
|
186
|
+
url: z
|
|
187
|
+
.string()
|
|
188
|
+
.min(1)
|
|
189
|
+
.meta(meta({ secret: true, description: "Redis connection URL" })),
|
|
190
|
+
})
|
|
191
|
+
.prefault({}),
|
|
192
|
+
masterKey: masterKey.meta(meta({ secret: true, description: "Base64 master key (32 bytes) for secret encryption" })),
|
|
193
|
+
masterKeyPrevious: z
|
|
194
|
+
.array(masterKey)
|
|
195
|
+
.default([])
|
|
196
|
+
.meta(meta({ secret: true, description: "Previous master keys kept during rotation" })),
|
|
197
|
+
extensions: z
|
|
198
|
+
.array(z.string())
|
|
199
|
+
.default([])
|
|
200
|
+
.meta(meta({ description: "Extension names to load" })),
|
|
201
|
+
extensionConfig: z
|
|
202
|
+
.record(z.string(), z.unknown())
|
|
203
|
+
.default({})
|
|
204
|
+
.meta(meta({ description: "Deployment-level config keyed by extension name" })),
|
|
205
|
+
extensionHost: z
|
|
206
|
+
.object({
|
|
207
|
+
dir: z
|
|
208
|
+
.string()
|
|
209
|
+
.min(1)
|
|
210
|
+
.default("/var/lib/capybara/plugins")
|
|
211
|
+
.meta(meta({
|
|
212
|
+
description: "Local directory where each replica unpacks installed extension packages (<dir>/<name>/<first 16 hex of sha256>/); safe to wipe, replicas re-download from the package store",
|
|
213
|
+
})),
|
|
214
|
+
drainSeconds: z
|
|
215
|
+
.number()
|
|
216
|
+
.int()
|
|
217
|
+
.positive()
|
|
218
|
+
.default(30)
|
|
219
|
+
.meta(meta({
|
|
220
|
+
description: "Seconds in-flight tool calls and queue jobs of an extension being unloaded may keep running before they are aborted",
|
|
221
|
+
})),
|
|
222
|
+
disposeTimeoutSeconds: z
|
|
223
|
+
.number()
|
|
224
|
+
.int()
|
|
225
|
+
.positive()
|
|
226
|
+
.default(10)
|
|
227
|
+
.meta(meta({
|
|
228
|
+
description: "Seconds an extension's dispose() may run when it is unloaded or replaced; after that the kernel logs a warning and moves on",
|
|
229
|
+
})),
|
|
230
|
+
reloadSetupTimeoutSeconds: z
|
|
231
|
+
.number()
|
|
232
|
+
.int()
|
|
233
|
+
.positive()
|
|
234
|
+
.default(60)
|
|
235
|
+
.meta(meta({
|
|
236
|
+
description: "Seconds an extension's setup() may run when it is reloaded in a running process (enable, upgrade, dependency change), and when an installed extension (install record) is loaded at startup; on timeout the load fails and the previous instance, if any, stays. Built-in and config-declared extensions are not bounded at startup",
|
|
237
|
+
})),
|
|
238
|
+
migrationTimeoutSeconds: z
|
|
239
|
+
.number()
|
|
240
|
+
.int()
|
|
241
|
+
.positive()
|
|
242
|
+
.default(300)
|
|
243
|
+
.meta(meta({
|
|
244
|
+
description: "Seconds an installed extension's migrations may run on the replica holding the migration lock; on timeout the migration session is terminated (statement_timeout bounds each statement, lock_timeout bounds lock waits), the lock is released and the replica reports migration_failed (retried on the next reconcile). Built-in and config-declared extensions are not bounded",
|
|
245
|
+
})),
|
|
246
|
+
reconcileIntervalSeconds: z
|
|
247
|
+
.number()
|
|
248
|
+
.int()
|
|
249
|
+
.positive()
|
|
250
|
+
.default(60)
|
|
251
|
+
.meta(meta({
|
|
252
|
+
description: "Seconds between periodic reconciles of each replica's loaded extensions against the installed state in PostgreSQL",
|
|
253
|
+
})),
|
|
254
|
+
})
|
|
255
|
+
.prefault({}),
|
|
256
|
+
packages: z
|
|
257
|
+
.object({
|
|
258
|
+
npmRegistry: z
|
|
259
|
+
.url()
|
|
260
|
+
.default("https://registry.npmjs.org")
|
|
261
|
+
.meta(meta({ description: "npm registry used to install extension packages by name" })),
|
|
262
|
+
npmToken: z
|
|
263
|
+
.string()
|
|
264
|
+
.min(1)
|
|
265
|
+
.optional()
|
|
266
|
+
.meta(meta({
|
|
267
|
+
secret: true,
|
|
268
|
+
description: "Bearer token for the npm registry (private registries); sent only to the registry origin",
|
|
269
|
+
})),
|
|
270
|
+
maxBytes: z
|
|
271
|
+
.number()
|
|
272
|
+
.int()
|
|
273
|
+
.positive()
|
|
274
|
+
.default(PACKAGES_MAX_BYTES_DEFAULT)
|
|
275
|
+
.meta(meta({
|
|
276
|
+
description: "Largest extension package (.tgz) in bytes accepted by upload, npm install and the PostgreSQL package store. Lowering it also caps what replicas read back from the object store, so packages accepted earlier under a larger limit can no longer be synced. Uploads through the web tier (apps/web) are also capped by its own CAPYBARA_WEB_MAX_PACKAGE_BYTES (default 50 MiB); raise both together",
|
|
277
|
+
})),
|
|
278
|
+
})
|
|
279
|
+
.prefault({}),
|
|
280
|
+
catalog: z
|
|
281
|
+
.object({
|
|
282
|
+
staleInstallMinutes: z
|
|
283
|
+
.number()
|
|
284
|
+
.int()
|
|
285
|
+
.positive()
|
|
286
|
+
.default(30)
|
|
287
|
+
.meta(meta({
|
|
288
|
+
description: "Minutes after which an organization plugin install still in the installing state (e.g. the replica crashed mid-install) may be cleaned up through uninstall, which rolls back the components it recorded",
|
|
289
|
+
})),
|
|
290
|
+
})
|
|
291
|
+
.prefault({}),
|
|
292
|
+
marketplaces: z
|
|
293
|
+
.object({
|
|
294
|
+
official: z
|
|
295
|
+
.object({
|
|
296
|
+
enabled: z
|
|
297
|
+
.boolean()
|
|
298
|
+
.default(true)
|
|
299
|
+
.meta(meta({
|
|
300
|
+
description: "Use the official marketplace (the capybara-hq/plugins repository). Set to false for an offline deployment: while false it is never fetched (no requests, no refresh logs) and the admin UI shows offline mode",
|
|
301
|
+
})),
|
|
302
|
+
url: z
|
|
303
|
+
.url({ protocol: /^https?$/ })
|
|
304
|
+
.default(MARKETPLACE_OFFICIAL_URL_DEFAULT)
|
|
305
|
+
.meta(meta({
|
|
306
|
+
description: "Address of the official marketplace (https): a git repository (a path ending in .git, read at its default branch from .capybara-plugin/marketplace.json) or a marketplace.json URL",
|
|
307
|
+
})),
|
|
308
|
+
mirrors: z
|
|
309
|
+
.array(z.url({ protocol: /^https?$/ }))
|
|
310
|
+
.max(MARKETPLACE_MAX_MIRRORS)
|
|
311
|
+
.default([])
|
|
312
|
+
.meta(meta({
|
|
313
|
+
description: "Mirror URLs of the official marketplace's marketplace.json (https), tried in order when the main URL fails; only for a marketplace.json URL (a git marketplace has no mirrors: point url at a mirror repository instead)",
|
|
314
|
+
})),
|
|
315
|
+
})
|
|
316
|
+
// Same rule as an enterprise marketplace: a git marketplace has no mirrors.
|
|
317
|
+
.refine((o) => o.mirrors.length === 0 || !isGitMarketplaceUrl(o.url), {
|
|
318
|
+
message: "a git marketplace has no mirrors (point marketplaces.official.url at a mirror repository instead)",
|
|
319
|
+
path: ["mirrors"],
|
|
320
|
+
})
|
|
321
|
+
.prefault({}),
|
|
322
|
+
refreshIntervalMinutes: z
|
|
323
|
+
.number()
|
|
324
|
+
.int()
|
|
325
|
+
.min(1)
|
|
326
|
+
.default(360)
|
|
327
|
+
.meta(meta({
|
|
328
|
+
description: "Minutes between periodic refreshes of every enabled marketplace (one maintenance job for all replicas)",
|
|
329
|
+
})),
|
|
330
|
+
maxIndexBytes: z
|
|
331
|
+
.number()
|
|
332
|
+
.int()
|
|
333
|
+
.positive()
|
|
334
|
+
.default(5_242_880)
|
|
335
|
+
.meta(meta({
|
|
336
|
+
description: "Largest marketplace.json in bytes; a larger response is rejected and the previous entries are kept",
|
|
337
|
+
})),
|
|
338
|
+
allowInsecureLoopback: z
|
|
339
|
+
.boolean()
|
|
340
|
+
.default(false)
|
|
341
|
+
.meta(meta({
|
|
342
|
+
description: "Testing only: allow plain http for marketplace and tarball URLs on loopback addresses",
|
|
343
|
+
})),
|
|
344
|
+
allowPrivateHosts: z
|
|
345
|
+
.array(z.string().superRefine((entry, ctx) => {
|
|
346
|
+
const problem = privateHostEntryProblem(entry);
|
|
347
|
+
if (problem !== null)
|
|
348
|
+
ctx.addIssue({ code: "custom", message: problem });
|
|
349
|
+
}))
|
|
350
|
+
.max(100)
|
|
351
|
+
.default([])
|
|
352
|
+
.meta(meta({
|
|
353
|
+
description: "Hosts or CIDRs that marketplace and git downloads may reach although they resolve to private addresses, e.g. an internal GitLab mirror. CIDR and IP entries match IP-literal hosts only; list internal DNS names as hostnames. Link-local addresses (169.254.0.0/16, fe80::/10) are always refused",
|
|
354
|
+
})),
|
|
355
|
+
allowedHosts: z
|
|
356
|
+
.array(z
|
|
357
|
+
.string()
|
|
358
|
+
.min(1)
|
|
359
|
+
.max(253)
|
|
360
|
+
.superRefine((entry, ctx) => {
|
|
361
|
+
const problem = allowedHostProblem(entry);
|
|
362
|
+
if (problem !== undefined)
|
|
363
|
+
ctx.addIssue({ code: "custom", message: problem });
|
|
364
|
+
})
|
|
365
|
+
.transform((h) => h.toLowerCase()))
|
|
366
|
+
.max(100)
|
|
367
|
+
.default([])
|
|
368
|
+
.meta(meta({
|
|
369
|
+
description: "Hosts that marketplace entries may download git and archive sources from: hostnames or IP addresses (IPv6 without brackets), without scheme or port, compared case-insensitively with the URL's hostname. Empty means unrestricted; an entry on another host is listed as not importable and its import is refused",
|
|
370
|
+
})),
|
|
371
|
+
})
|
|
372
|
+
.prefault({}),
|
|
373
|
+
net: z
|
|
374
|
+
.object({
|
|
375
|
+
httpsProxy: z
|
|
376
|
+
.string()
|
|
377
|
+
.superRefine((value, ctx) => {
|
|
378
|
+
const problem = proxyUrlProblem(value);
|
|
379
|
+
if (problem !== undefined)
|
|
380
|
+
ctx.addIssue({ code: "custom", message: problem });
|
|
381
|
+
})
|
|
382
|
+
.optional()
|
|
383
|
+
.meta(meta({
|
|
384
|
+
secret: true,
|
|
385
|
+
description: "HTTP(S) egress proxy for marketplace, archive and git downloads, e.g. http://user:password@proxy.internal:3128. https downloads tunnel through it with CONNECT and the kernel no longer resolves their hosts: the proxy does, so blocking private and internal addresses becomes the proxy's job (IP-literal URLs are still checked against marketplaces.allowPrivateHosts). Loopback hosts never use it. Credentials in the URL are sent as Basic Proxy-Authorization and never logged",
|
|
386
|
+
})),
|
|
387
|
+
noProxy: z
|
|
388
|
+
.array(z
|
|
389
|
+
.string()
|
|
390
|
+
.min(1)
|
|
391
|
+
.max(253)
|
|
392
|
+
.superRefine((entry, ctx) => {
|
|
393
|
+
const problem = noProxyEntryProblem(entry);
|
|
394
|
+
if (problem !== undefined)
|
|
395
|
+
ctx.addIssue({ code: "custom", message: problem });
|
|
396
|
+
}))
|
|
397
|
+
.max(100)
|
|
398
|
+
.default([])
|
|
399
|
+
.meta(meta({
|
|
400
|
+
description: "Hostnames or IP addresses that bypass net.httpsProxy (an entry also matches its subdomains; a leading dot is allowed). These hosts are resolved locally and must resolve to public addresses unless listed in marketplaces.allowPrivateHosts",
|
|
401
|
+
})),
|
|
402
|
+
})
|
|
403
|
+
.prefault({}),
|
|
404
|
+
extensionPermissions: z
|
|
405
|
+
.object({
|
|
406
|
+
autoApprove: z
|
|
407
|
+
.boolean()
|
|
408
|
+
.default(false)
|
|
409
|
+
.meta(meta({
|
|
410
|
+
description: "Approve extension permissions automatically at startup (development and trials only). When false, an extension that is new or whose upgrade asks for more permissions is not loaded until an admin runs `capybara extensions approve <name>`",
|
|
411
|
+
})),
|
|
412
|
+
})
|
|
413
|
+
.default({ autoApprove: false }),
|
|
414
|
+
http: z
|
|
415
|
+
.object({
|
|
416
|
+
port: z
|
|
417
|
+
.number()
|
|
418
|
+
.int()
|
|
419
|
+
.min(0)
|
|
420
|
+
.max(65535)
|
|
421
|
+
.default(8080)
|
|
422
|
+
.meta(meta({ description: "HTTP listen port" })),
|
|
423
|
+
trustProxy: z
|
|
424
|
+
.preprocess(
|
|
425
|
+
// Also accept a comma-separated string of addresses / CIDRs (an env value that is not JSON
|
|
426
|
+
// arrives as a string, e.g. CAPYBARA_HTTP__TRUST_PROXY=172.18.0.1,10.0.0.0/8).
|
|
427
|
+
(v) => typeof v === "string"
|
|
428
|
+
? v
|
|
429
|
+
.split(",")
|
|
430
|
+
.map((e) => e.trim())
|
|
431
|
+
.filter((e) => e !== "")
|
|
432
|
+
: v, z.union([
|
|
433
|
+
z.boolean(),
|
|
434
|
+
z.number().int().min(1),
|
|
435
|
+
z
|
|
436
|
+
.array(z
|
|
437
|
+
.string()
|
|
438
|
+
.min(1)
|
|
439
|
+
.superRefine((e, ctx) => {
|
|
440
|
+
const problem = trustProxyEntryProblem(e);
|
|
441
|
+
if (problem !== undefined)
|
|
442
|
+
ctx.addIssue({ code: "custom", message: problem });
|
|
443
|
+
}))
|
|
444
|
+
.min(1),
|
|
445
|
+
]))
|
|
446
|
+
.default(false)
|
|
447
|
+
.meta(meta({
|
|
448
|
+
description: "Which X-Forwarded-For hops to trust for the client IP (login rate limiting, session records): false (use the socket address), a hop count, or a list of trusted proxy IPs/CIDRs (recommended; a JSON array or a comma-separated string; a /0 prefix is refused). true trusts any client-supplied X-Forwarded-For and lets clients spoof their IP. A hop count is only safe when the service is reachable solely through exactly that many proxies",
|
|
449
|
+
})),
|
|
450
|
+
// 环境变量按 JSON 解析,CAPYBARA_HTTP__REPLICA_ID=0 会得到数字,所以也接受非负整数(输出头时转字符串)
|
|
451
|
+
replicaId: z
|
|
452
|
+
.union([
|
|
453
|
+
z
|
|
454
|
+
.string()
|
|
455
|
+
.min(1)
|
|
456
|
+
.max(64)
|
|
457
|
+
.regex(/^[A-Za-z0-9._-]+$/),
|
|
458
|
+
z.number().int().nonnegative(),
|
|
459
|
+
])
|
|
460
|
+
.optional()
|
|
461
|
+
.meta(meta({
|
|
462
|
+
description: "Optional replica identifier; when set, every HTTP response carries an x-capybara-replica header with this value (used by the dual-replica test harness and for debugging load balancers)",
|
|
463
|
+
})),
|
|
464
|
+
publicUrl: z
|
|
465
|
+
.url()
|
|
466
|
+
.optional()
|
|
467
|
+
.meta(meta({
|
|
468
|
+
description: "Externally reachable origin of the web app (apps/web, which proxies /api to the kernel), not the kernel's own address; required for OAuth connectors: the redirect URI is <publicUrl>/api/v1/oauth/callback (served through the web /api proxy, which also carries the OAuth binding cookie) and the callback redirects to web pages under it, e.g. https://capybara.example.com",
|
|
469
|
+
})),
|
|
470
|
+
})
|
|
471
|
+
.default({ port: 8080, trustProxy: false }),
|
|
472
|
+
roles: z
|
|
473
|
+
.preprocess(
|
|
474
|
+
// Also accept a comma-separated string (CAPYBARA_ROLES=api,worker; env values that are not
|
|
475
|
+
// JSON arrive as strings).
|
|
476
|
+
(v) => typeof v === "string"
|
|
477
|
+
? v
|
|
478
|
+
.split(",")
|
|
479
|
+
.map((r) => r.trim())
|
|
480
|
+
.filter((r) => r !== "")
|
|
481
|
+
: v, z.array(z.enum(["api", "worker", "gateway"])).min(1))
|
|
482
|
+
.default(["api", "worker", "gateway"])
|
|
483
|
+
.meta(meta({
|
|
484
|
+
description: 'Roles this process runs: a JSON array or a comma-separated string, e.g. ["api"] or api,worker',
|
|
485
|
+
})),
|
|
486
|
+
auth: z
|
|
487
|
+
.object({
|
|
488
|
+
accessTokenTtlSeconds: z
|
|
489
|
+
.number()
|
|
490
|
+
.int()
|
|
491
|
+
.min(60)
|
|
492
|
+
.max(ACCESS_TOKEN_TTL_MAX_SECONDS)
|
|
493
|
+
.default(900)
|
|
494
|
+
.meta(meta({ description: "Lifetime of web session access tokens in seconds" })),
|
|
495
|
+
refreshTokenTtlDays: z
|
|
496
|
+
.number()
|
|
497
|
+
.int()
|
|
498
|
+
.min(1)
|
|
499
|
+
.max(365)
|
|
500
|
+
.default(30)
|
|
501
|
+
.meta(meta({
|
|
502
|
+
description: "Absolute lifetime of a web session (refresh token) in days; refreshing does not extend it",
|
|
503
|
+
})),
|
|
504
|
+
cookieSecure: z
|
|
505
|
+
.boolean()
|
|
506
|
+
.default(true)
|
|
507
|
+
.meta(meta({
|
|
508
|
+
description: "Set the Secure attribute on session cookies; set false only for local trials over plain http",
|
|
509
|
+
})),
|
|
510
|
+
setupToken: z
|
|
511
|
+
// An empty value means "not set" (compose passes ${CAPYBARA_SETUP_TOKEN:-}). Env values are
|
|
512
|
+
// JSON-parsed, so an all-digit or true / false token arrives as a number or boolean: it is
|
|
513
|
+
// still the token text.
|
|
514
|
+
.preprocess((v) => v === "" ? undefined : typeof v === "number" || typeof v === "boolean" ? String(v) : v, z.string().min(1).optional())
|
|
515
|
+
.optional()
|
|
516
|
+
.meta(meta({ secret: true, description: "If set, the setup wizard requires this token" })),
|
|
517
|
+
loginSources: z
|
|
518
|
+
.array(z.string().min(1).max(214))
|
|
519
|
+
.max(50)
|
|
520
|
+
.default([])
|
|
521
|
+
.meta(meta({
|
|
522
|
+
hot: true,
|
|
523
|
+
description: "Extension names (providing identity-source@1) offered as third-party sign-in on the login page, in this order; the sign-in callback URL is <http.publicUrl>/api/v1/auth/sso/<plugin>/callback",
|
|
524
|
+
})),
|
|
525
|
+
trustedIdentitySources: z
|
|
526
|
+
.array(z
|
|
527
|
+
.string()
|
|
528
|
+
.max(471)
|
|
529
|
+
.refine((v) => TRUSTED_SOURCE_RE.test(v), {
|
|
530
|
+
message: 'Each entry must be a full identity source key "<plugin>:<tenantId>" (for example "lark:tenant_1"); plugin-only entries are not allowed, trust is per tenant',
|
|
531
|
+
}))
|
|
532
|
+
.max(50)
|
|
533
|
+
.default([])
|
|
534
|
+
.meta(meta({
|
|
535
|
+
hot: true,
|
|
536
|
+
description: 'Identity source keys "<plugin>:<tenantId>" (one tenant each, e.g. "lark:tenant_1") whose external identities are trusted: on third-party sign-in, when the identity\'s email and an existing account\'s email are both verified and equal, the identity is linked to that account instead of creating a new one; and accounts created through a trusted source count as email-verified. Only list tenants (workspaces / apps) that your enterprise controls; otherwise anyone in that tenant could claim your users\' emails. Entries without a tenant id are rejected',
|
|
537
|
+
})),
|
|
538
|
+
})
|
|
539
|
+
.default({
|
|
540
|
+
accessTokenTtlSeconds: 900,
|
|
541
|
+
refreshTokenTtlDays: 30,
|
|
542
|
+
cookieSecure: true,
|
|
543
|
+
loginSources: [],
|
|
544
|
+
trustedIdentitySources: [],
|
|
545
|
+
}),
|
|
546
|
+
runtime: z
|
|
547
|
+
.object({
|
|
548
|
+
maxSteps: z
|
|
549
|
+
.number()
|
|
550
|
+
.int()
|
|
551
|
+
.positive()
|
|
552
|
+
.default(50)
|
|
553
|
+
.meta(meta({ description: "Maximum model steps per agent run before the final wrap-up" })),
|
|
554
|
+
maxRunSeconds: z
|
|
555
|
+
.number()
|
|
556
|
+
.int()
|
|
557
|
+
.positive()
|
|
558
|
+
.default(DEFAULT_MAX_RUN_SECONDS)
|
|
559
|
+
.meta(meta({
|
|
560
|
+
description: "Maximum wall-clock duration of one agent run in seconds (time spent waiting for people is not counted). Sandbox commands are limited to the time left in the run, so agents that need long commands need maxRunSeconds >= sandbox.limits.maxCommandSeconds",
|
|
561
|
+
})),
|
|
562
|
+
streamIdleMs: z
|
|
563
|
+
.number()
|
|
564
|
+
.int()
|
|
565
|
+
.positive()
|
|
566
|
+
.default(60000)
|
|
567
|
+
.meta(meta({
|
|
568
|
+
description: "Default model stream idle watchdog in milliseconds (a model's own streamIdleTimeoutMs takes precedence)",
|
|
569
|
+
})),
|
|
570
|
+
maxOutputTokens: z
|
|
571
|
+
.number()
|
|
572
|
+
.int()
|
|
573
|
+
.positive()
|
|
574
|
+
.default(16000)
|
|
575
|
+
.meta(meta({
|
|
576
|
+
description: "Default output-token limit per model call when the agent does not set maxOutputTokens (an agent's maxOutputTokens overrides it; either is capped by the model's own maximum)",
|
|
577
|
+
})),
|
|
578
|
+
compactionThreshold: z
|
|
579
|
+
.number()
|
|
580
|
+
.gt(0)
|
|
581
|
+
.max(1)
|
|
582
|
+
.default(0.8)
|
|
583
|
+
.meta(meta({
|
|
584
|
+
description: "Compact the conversation when the estimated input reaches this fraction of the context window",
|
|
585
|
+
})),
|
|
586
|
+
keepRecentTurns: z
|
|
587
|
+
.number()
|
|
588
|
+
.int()
|
|
589
|
+
.nonnegative()
|
|
590
|
+
.default(4)
|
|
591
|
+
.meta(meta({ description: "Number of recent user turns kept verbatim when compacting" })),
|
|
592
|
+
workerConcurrency: z
|
|
593
|
+
.number()
|
|
594
|
+
.int()
|
|
595
|
+
.positive()
|
|
596
|
+
.default(10)
|
|
597
|
+
.meta(meta({ description: "Maximum agent runs executed concurrently by one worker process" })),
|
|
598
|
+
orgConcurrency: z
|
|
599
|
+
.number()
|
|
600
|
+
.int()
|
|
601
|
+
.positive()
|
|
602
|
+
.default(10)
|
|
603
|
+
.meta(meta({
|
|
604
|
+
hot: true,
|
|
605
|
+
description: "Maximum agent runs executing concurrently per organization across all replicas",
|
|
606
|
+
})),
|
|
607
|
+
jobLockMs: z
|
|
608
|
+
.number()
|
|
609
|
+
.int()
|
|
610
|
+
.positive()
|
|
611
|
+
.default(30000)
|
|
612
|
+
.meta(meta({
|
|
613
|
+
description: "Lock duration of an agent run job in milliseconds (BullMQ lockDuration), also the TTL of the conversation run lock; a run whose worker stops renewing them is considered stalled after this long and resumes on another worker",
|
|
614
|
+
})),
|
|
615
|
+
stalledIntervalMs: z
|
|
616
|
+
.number()
|
|
617
|
+
.int()
|
|
618
|
+
.positive()
|
|
619
|
+
.default(30000)
|
|
620
|
+
.meta(meta({
|
|
621
|
+
description: "How often workers check for stalled agent run jobs in milliseconds (BullMQ stalledInterval)",
|
|
622
|
+
})),
|
|
623
|
+
sseHeartbeatMs: z
|
|
624
|
+
.number()
|
|
625
|
+
.int()
|
|
626
|
+
.positive()
|
|
627
|
+
.default(15000)
|
|
628
|
+
.meta(meta({
|
|
629
|
+
description: "Interval in milliseconds between heartbeat comments on a conversation event stream (SSE)",
|
|
630
|
+
})),
|
|
631
|
+
sseRecheckMs: z
|
|
632
|
+
.number()
|
|
633
|
+
.int()
|
|
634
|
+
.positive()
|
|
635
|
+
.default(60000)
|
|
636
|
+
.meta(meta({
|
|
637
|
+
description: "How often an open conversation event stream (SSE) re-checks that the viewer may still access the conversation, in milliseconds; the stream closes when access is lost",
|
|
638
|
+
})),
|
|
639
|
+
})
|
|
640
|
+
.default({
|
|
641
|
+
maxSteps: 50,
|
|
642
|
+
maxRunSeconds: DEFAULT_MAX_RUN_SECONDS,
|
|
643
|
+
streamIdleMs: 60000,
|
|
644
|
+
maxOutputTokens: 16000,
|
|
645
|
+
compactionThreshold: 0.8,
|
|
646
|
+
keepRecentTurns: 4,
|
|
647
|
+
workerConcurrency: 10,
|
|
648
|
+
orgConcurrency: 10,
|
|
649
|
+
jobLockMs: 30000,
|
|
650
|
+
stalledIntervalMs: 30000,
|
|
651
|
+
sseHeartbeatMs: 15000,
|
|
652
|
+
sseRecheckMs: 60000,
|
|
653
|
+
}),
|
|
654
|
+
tools: z
|
|
655
|
+
.object({
|
|
656
|
+
timeoutMs: z
|
|
657
|
+
.number()
|
|
658
|
+
.int()
|
|
659
|
+
.positive()
|
|
660
|
+
.default(60000)
|
|
661
|
+
.meta(meta({ description: "Timeout of one tool call in milliseconds" })),
|
|
662
|
+
breakerFailures: z
|
|
663
|
+
.number()
|
|
664
|
+
.int()
|
|
665
|
+
.positive()
|
|
666
|
+
.default(5)
|
|
667
|
+
.meta(meta({
|
|
668
|
+
description: "Consecutive failures of one connector that open its circuit breaker",
|
|
669
|
+
})),
|
|
670
|
+
breakerOpenSeconds: z
|
|
671
|
+
.number()
|
|
672
|
+
.int()
|
|
673
|
+
.positive()
|
|
674
|
+
.default(60)
|
|
675
|
+
.meta(meta({
|
|
676
|
+
description: "Seconds an open circuit breaker rejects calls before allowing a probe",
|
|
677
|
+
})),
|
|
678
|
+
outputSpillChars: z
|
|
679
|
+
.number()
|
|
680
|
+
.int()
|
|
681
|
+
.positive()
|
|
682
|
+
.default(50000)
|
|
683
|
+
.meta(meta({
|
|
684
|
+
description: "Tool results longer than this many characters are archived and replaced by a preview",
|
|
685
|
+
})),
|
|
686
|
+
outputPreviewChars: z
|
|
687
|
+
.number()
|
|
688
|
+
.int()
|
|
689
|
+
.positive()
|
|
690
|
+
.default(2000)
|
|
691
|
+
.meta(meta({
|
|
692
|
+
description: "Characters of an archived tool result kept in the conversation as a preview",
|
|
693
|
+
})),
|
|
694
|
+
outputRetentionDays: z
|
|
695
|
+
.number()
|
|
696
|
+
.int()
|
|
697
|
+
.positive()
|
|
698
|
+
.default(30)
|
|
699
|
+
.meta(meta({ description: "Days archived tool outputs are kept before cleanup" })),
|
|
700
|
+
approvalTimeoutHours: z
|
|
701
|
+
.number()
|
|
702
|
+
.int()
|
|
703
|
+
.positive()
|
|
704
|
+
.default(24)
|
|
705
|
+
.meta(meta({
|
|
706
|
+
description: "Hours a pending approval or question waits before it expires (treated as denied)",
|
|
707
|
+
})),
|
|
708
|
+
searchThresholdTools: z
|
|
709
|
+
.number()
|
|
710
|
+
.int()
|
|
711
|
+
.positive()
|
|
712
|
+
.default(30)
|
|
713
|
+
.meta(meta({
|
|
714
|
+
description: "Switch to on-demand tool search when an agent has more than this many tools",
|
|
715
|
+
})),
|
|
716
|
+
searchThresholdTokens: z
|
|
717
|
+
.number()
|
|
718
|
+
.int()
|
|
719
|
+
.positive()
|
|
720
|
+
.default(8000)
|
|
721
|
+
.meta(meta({
|
|
722
|
+
description: "Switch to on-demand tool search when tool definitions exceed this many estimated tokens",
|
|
723
|
+
})),
|
|
724
|
+
driftIntervalHours: z
|
|
725
|
+
.number()
|
|
726
|
+
.int()
|
|
727
|
+
.positive()
|
|
728
|
+
.default(24)
|
|
729
|
+
.meta(meta({
|
|
730
|
+
description: "Hours between checks of connectors for changed tool definitions",
|
|
731
|
+
})),
|
|
732
|
+
maxResultReadChars: z
|
|
733
|
+
.number()
|
|
734
|
+
.int()
|
|
735
|
+
.positive()
|
|
736
|
+
.default(20000)
|
|
737
|
+
.meta(meta({ description: "Maximum characters returned by one read_tool_output call" })),
|
|
738
|
+
oauthAllowInsecureLoopback: z
|
|
739
|
+
.boolean()
|
|
740
|
+
.default(false)
|
|
741
|
+
.meta(meta({
|
|
742
|
+
description: "Allow OAuth discovery, registration and token endpoints over plain http on loopback hosts (development and tests only; production requires https)",
|
|
743
|
+
})),
|
|
744
|
+
})
|
|
745
|
+
.default({
|
|
746
|
+
timeoutMs: 60000,
|
|
747
|
+
breakerFailures: 5,
|
|
748
|
+
breakerOpenSeconds: 60,
|
|
749
|
+
outputSpillChars: 50000,
|
|
750
|
+
outputPreviewChars: 2000,
|
|
751
|
+
outputRetentionDays: 30,
|
|
752
|
+
approvalTimeoutHours: 24,
|
|
753
|
+
searchThresholdTools: 30,
|
|
754
|
+
searchThresholdTokens: 8000,
|
|
755
|
+
driftIntervalHours: 24,
|
|
756
|
+
maxResultReadChars: 20000,
|
|
757
|
+
oauthAllowInsecureLoopback: false,
|
|
758
|
+
}),
|
|
759
|
+
channels: z
|
|
760
|
+
.object({
|
|
761
|
+
leaseTtlMs: z
|
|
762
|
+
.number()
|
|
763
|
+
.int()
|
|
764
|
+
.positive()
|
|
765
|
+
.default(30000)
|
|
766
|
+
.meta(meta({
|
|
767
|
+
description: "TTL of the lease that lets one gateway replica hold a channel connection's long connection, in milliseconds; another replica takes over after the holder stops renewing it for this long",
|
|
768
|
+
})),
|
|
769
|
+
scanIntervalMs: z
|
|
770
|
+
.number()
|
|
771
|
+
.int()
|
|
772
|
+
.positive()
|
|
773
|
+
.default(10000)
|
|
774
|
+
.meta(meta({
|
|
775
|
+
description: "How often each gateway replica renews its channel leases and scans for active channel connections that nobody holds, in milliseconds",
|
|
776
|
+
})),
|
|
777
|
+
shareSlack: z
|
|
778
|
+
.number()
|
|
779
|
+
.int()
|
|
780
|
+
.nonnegative()
|
|
781
|
+
.default(1)
|
|
782
|
+
.meta(meta({
|
|
783
|
+
description: "Extra channel long connections a gateway replica may hold above its fair share (connections divided by live gateway replicas); a replica above share + slack hands one back per scan round",
|
|
784
|
+
})),
|
|
785
|
+
retryBaseMs: z
|
|
786
|
+
.number()
|
|
787
|
+
.int()
|
|
788
|
+
.positive()
|
|
789
|
+
.default(5000)
|
|
790
|
+
.meta(meta({
|
|
791
|
+
description: "First retry delay after a channel long connection fails, in milliseconds; doubles on each consecutive failure up to 5 minutes",
|
|
792
|
+
})),
|
|
793
|
+
deliveryConcurrency: z
|
|
794
|
+
.number()
|
|
795
|
+
.int()
|
|
796
|
+
.positive()
|
|
797
|
+
.default(100)
|
|
798
|
+
.meta(meta({
|
|
799
|
+
description: "How many channel outbound delivery jobs one worker replica runs at the same time (each job follows one conversation while its run streams output)",
|
|
800
|
+
})),
|
|
801
|
+
deliveryIdleMs: z
|
|
802
|
+
.number()
|
|
803
|
+
.int()
|
|
804
|
+
.positive()
|
|
805
|
+
.default(15000)
|
|
806
|
+
.meta(meta({
|
|
807
|
+
description: "A channel delivery job that has caught up ends after this many milliseconds without new conversation output; the next event of the conversation starts a new job",
|
|
808
|
+
})),
|
|
809
|
+
webhookBaseUrl: z
|
|
810
|
+
.url({ protocol: /^https?$/ })
|
|
811
|
+
.optional()
|
|
812
|
+
.meta(meta({
|
|
813
|
+
description: "Public origin (https) that reaches the gateway replicas, e.g. https://im.example.com; a channel connection's webhook callback URL is <webhookBaseUrl>/channels/webhook/<connection id>. Without it connections cannot switch to webhook inbound (long connections stay the default). Plain http is accepted only for loopback hosts when tools.oauthAllowInsecureLoopback is true (tests)",
|
|
814
|
+
})),
|
|
815
|
+
webhookMaxBodyBytes: z
|
|
816
|
+
.number()
|
|
817
|
+
.int()
|
|
818
|
+
.positive()
|
|
819
|
+
.default(1_048_576)
|
|
820
|
+
.meta(meta({
|
|
821
|
+
description: "Largest channel webhook request body in bytes; a larger request is rejected with 413",
|
|
822
|
+
})),
|
|
823
|
+
})
|
|
824
|
+
// 续租周期必须明显短于 TTL:至少能在租约过期前续两次,偶尔一次 Redis 抖动不至于丢租约
|
|
825
|
+
.refine((c) => c.scanIntervalMs <= c.leaseTtlMs / 2, {
|
|
826
|
+
message: "channels.scanIntervalMs must be at most half of channels.leaseTtlMs",
|
|
827
|
+
path: ["scanIntervalMs"],
|
|
828
|
+
})
|
|
829
|
+
.default({
|
|
830
|
+
leaseTtlMs: 30000,
|
|
831
|
+
scanIntervalMs: 10000,
|
|
832
|
+
shareSlack: 1,
|
|
833
|
+
retryBaseMs: 5000,
|
|
834
|
+
deliveryConcurrency: 100,
|
|
835
|
+
deliveryIdleMs: 15000,
|
|
836
|
+
webhookMaxBodyBytes: 1_048_576,
|
|
837
|
+
}),
|
|
838
|
+
storage: z
|
|
839
|
+
.object({
|
|
840
|
+
purgeDeletedOrgsAfterDays: z
|
|
841
|
+
.number()
|
|
842
|
+
.int()
|
|
843
|
+
.nonnegative()
|
|
844
|
+
.default(30)
|
|
845
|
+
.meta(meta({
|
|
846
|
+
description: "Days after an organization is deleted before a maintenance job permanently deletes its objects from object storage (kernel/<orgId>/ and plugins/*/<orgId>/)",
|
|
847
|
+
})),
|
|
848
|
+
})
|
|
849
|
+
.default({ purgeDeletedOrgsAfterDays: 30 }),
|
|
850
|
+
attachments: z
|
|
851
|
+
.object({
|
|
852
|
+
maxBytes: z
|
|
853
|
+
.number()
|
|
854
|
+
.int()
|
|
855
|
+
.positive()
|
|
856
|
+
.default(20_971_520)
|
|
857
|
+
.meta(meta({
|
|
858
|
+
description: "Maximum size in bytes of one chat attachment (images are also capped at 5 MiB, the model input limit)",
|
|
859
|
+
})),
|
|
860
|
+
allowedTypes: z
|
|
861
|
+
.array(z.enum([...IMAGE_MEDIA_TYPES, ...DOCUMENT_MEDIA_TYPES]))
|
|
862
|
+
.min(1)
|
|
863
|
+
.default([...IMAGE_MEDIA_TYPES, ...DOCUMENT_MEDIA_TYPES])
|
|
864
|
+
.meta(meta({ description: "Content types accepted for chat attachments" })),
|
|
865
|
+
maxPerMessage: z
|
|
866
|
+
.number()
|
|
867
|
+
.int()
|
|
868
|
+
.min(1)
|
|
869
|
+
.max(100)
|
|
870
|
+
.default(10)
|
|
871
|
+
.meta(meta({ description: "Maximum number of attachments in one message" })),
|
|
872
|
+
unboundTtlHours: z
|
|
873
|
+
.number()
|
|
874
|
+
.int()
|
|
875
|
+
.positive()
|
|
876
|
+
.default(24)
|
|
877
|
+
.meta(meta({
|
|
878
|
+
description: "Hours after upload before an attachment never used in a message is deleted (row and object)",
|
|
879
|
+
})),
|
|
880
|
+
requestMediaBytes: z
|
|
881
|
+
.number()
|
|
882
|
+
.int()
|
|
883
|
+
.positive()
|
|
884
|
+
// base64 让字节膨胀约 4/3:24 MiB 原始字节 ≈ 32 MiB,正好压在常见供应商 32 MB 的请求上限内
|
|
885
|
+
.max(REQUEST_MEDIA_BYTES_MAX, {
|
|
886
|
+
message: "attachments.requestMediaBytes must be at most 25165824 (24 MiB)",
|
|
887
|
+
})
|
|
888
|
+
.default(20_971_520)
|
|
889
|
+
.meta(meta({
|
|
890
|
+
description: "Budget of raw attachment bytes in one model request; the newest attachments are kept and older ones are replaced with a placeholder. At most 24 MiB: base64 inflates it by about 4/3, and common providers cap a request at 32 MB",
|
|
891
|
+
})),
|
|
892
|
+
})
|
|
893
|
+
// 单个附件不能大于单次请求的预算:否则它永远被省略(最新的附件总能放进请求)
|
|
894
|
+
.refine((c) => c.maxBytes <= c.requestMediaBytes, {
|
|
895
|
+
message: "attachments.maxBytes must be at most attachments.requestMediaBytes",
|
|
896
|
+
path: ["maxBytes"],
|
|
897
|
+
})
|
|
898
|
+
.prefault({}),
|
|
899
|
+
subagents: z
|
|
900
|
+
.object({
|
|
901
|
+
maxConcurrentPerRun: z
|
|
902
|
+
.number()
|
|
903
|
+
.int()
|
|
904
|
+
.min(1)
|
|
905
|
+
.max(20)
|
|
906
|
+
.default(4)
|
|
907
|
+
.meta(meta({
|
|
908
|
+
hot: true,
|
|
909
|
+
description: "Sub-agents one run may have running at the same time; agent calls beyond it in one response are refused. Organizations can be given their own value in the deployment setting subagentLimitOverrides",
|
|
910
|
+
})),
|
|
911
|
+
maxDispatchesPerRun: z
|
|
912
|
+
.number()
|
|
913
|
+
.int()
|
|
914
|
+
.min(1)
|
|
915
|
+
.max(500)
|
|
916
|
+
.default(50)
|
|
917
|
+
.meta(meta({
|
|
918
|
+
hot: true,
|
|
919
|
+
description: "Sub-agents one run may dispatch in total, follow-ups included; later agent calls are refused. Organizations can be given their own value in subagentLimitOverrides",
|
|
920
|
+
})),
|
|
921
|
+
maxTokensPerRun: z
|
|
922
|
+
.number()
|
|
923
|
+
.int()
|
|
924
|
+
.min(10_000)
|
|
925
|
+
.default(5_000_000)
|
|
926
|
+
.meta(meta({
|
|
927
|
+
hot: true,
|
|
928
|
+
description: "Tokens (input, output and cache) the sub-agents of one run may use together; at the cap running sub-agents stop and new dispatches are refused. Organizations can be given their own value in subagentLimitOverrides",
|
|
929
|
+
})),
|
|
930
|
+
})
|
|
931
|
+
.prefault({}),
|
|
932
|
+
sandbox: z
|
|
933
|
+
.object({
|
|
934
|
+
image: z
|
|
935
|
+
.string()
|
|
936
|
+
.min(1)
|
|
937
|
+
.default("capybara-sandbox:latest")
|
|
938
|
+
.meta(meta({
|
|
939
|
+
description: "Image for conversation sandboxes, used by the Docker sandbox extension (built from plugins/sandbox-docker/image/Dockerfile; pre-pull it on every Docker node). The E2B extension ignores it and uses its own template setting",
|
|
940
|
+
})),
|
|
941
|
+
lockWaitSeconds: z
|
|
942
|
+
.number()
|
|
943
|
+
.positive()
|
|
944
|
+
.default(75)
|
|
945
|
+
.meta(meta({
|
|
946
|
+
description: "Seconds a sandbox call waits while another command in the same conversation holds the sandbox before failing with sandbox.busy; keep it above the 60-second sandbox lock TTL so a call after a replica crash waits for the dead replica's lock to expire",
|
|
947
|
+
})),
|
|
948
|
+
maxConcurrentCommands: z
|
|
949
|
+
.number()
|
|
950
|
+
.int()
|
|
951
|
+
.min(1)
|
|
952
|
+
.max(32)
|
|
953
|
+
.default(6)
|
|
954
|
+
.meta(meta({
|
|
955
|
+
hot: true,
|
|
956
|
+
description: "Sandbox commands and file operations that may run at the same time in one conversation's sandbox (parallel sub-agents share their parent conversation's sandbox); 1 runs them one at a time. Providers that do not declare concurrent exec always get 1",
|
|
957
|
+
})),
|
|
958
|
+
deliverMaxBytes: z
|
|
959
|
+
.number()
|
|
960
|
+
.int()
|
|
961
|
+
.positive()
|
|
962
|
+
.default(104_857_600)
|
|
963
|
+
.meta(meta({
|
|
964
|
+
description: "Largest file in bytes an agent may deliver from its sandbox to the user as an artifact (sandbox_deliver)",
|
|
965
|
+
})),
|
|
966
|
+
limits: z
|
|
967
|
+
.object({
|
|
968
|
+
cpu: z
|
|
969
|
+
.number()
|
|
970
|
+
.positive()
|
|
971
|
+
.default(1)
|
|
972
|
+
.meta(meta({
|
|
973
|
+
description: "CPU cores for each sandbox; applies to sandboxes created after the change (E2B: set in the template)",
|
|
974
|
+
})),
|
|
975
|
+
memoryMb: z
|
|
976
|
+
.number()
|
|
977
|
+
.int()
|
|
978
|
+
.positive()
|
|
979
|
+
.default(2048)
|
|
980
|
+
.meta(meta({
|
|
981
|
+
description: "Memory limit of each sandbox in MiB; applies to sandboxes created after the change (E2B: set in the template)",
|
|
982
|
+
})),
|
|
983
|
+
diskMb: z
|
|
984
|
+
.number()
|
|
985
|
+
.int()
|
|
986
|
+
.positive()
|
|
987
|
+
.default(5120)
|
|
988
|
+
.meta(meta({
|
|
989
|
+
description: "Disk limit of each sandbox in MiB; applies to sandboxes created after the change (Docker: only with a volume driver that supports size; E2B: set by the template / plan)",
|
|
990
|
+
})),
|
|
991
|
+
maxCommandSeconds: z
|
|
992
|
+
.number()
|
|
993
|
+
.int()
|
|
994
|
+
.positive()
|
|
995
|
+
.default(DEFAULT_MAX_COMMAND_SECONDS)
|
|
996
|
+
.meta(meta({
|
|
997
|
+
description: "Longest a single sandbox command may run, in seconds. A command also stops when its run is about to reach runtime.maxRunSeconds, so long commands need runtime.maxRunSeconds >= maxCommandSeconds (a startup warning is logged otherwise)",
|
|
998
|
+
})),
|
|
999
|
+
suspendAfterIdleMinutes: z
|
|
1000
|
+
.number()
|
|
1001
|
+
.int()
|
|
1002
|
+
.positive()
|
|
1003
|
+
.default(10)
|
|
1004
|
+
.meta(meta({
|
|
1005
|
+
description: "Minutes without use before a running sandbox is suspended (files are kept)",
|
|
1006
|
+
})),
|
|
1007
|
+
destroyAfterInactiveDays: z
|
|
1008
|
+
.number()
|
|
1009
|
+
.int()
|
|
1010
|
+
.positive()
|
|
1011
|
+
.default(7)
|
|
1012
|
+
.meta(meta({
|
|
1013
|
+
description: "Days without use before a sandbox is destroyed with its files; the next use starts an empty one",
|
|
1014
|
+
})),
|
|
1015
|
+
maxRunningMinutes: z
|
|
1016
|
+
.number()
|
|
1017
|
+
.int()
|
|
1018
|
+
.positive()
|
|
1019
|
+
.default(120)
|
|
1020
|
+
.meta(meta({
|
|
1021
|
+
description: "Minutes a sandbox may run continuously before it is suspended even while in use (skipped while a command is running)",
|
|
1022
|
+
})),
|
|
1023
|
+
egress: z
|
|
1024
|
+
.enum(["none", "allowlist", "open"])
|
|
1025
|
+
.default("allowlist")
|
|
1026
|
+
.meta(meta({
|
|
1027
|
+
description: "Outbound network from sandboxes: none, allowlist (only allowHosts) or open; applies to sandboxes created after the change, existing ones keep theirs until destroyed",
|
|
1028
|
+
})),
|
|
1029
|
+
allowHosts: z
|
|
1030
|
+
.array(z.string())
|
|
1031
|
+
.default([...DEFAULT_SANDBOX_ALLOW_HOSTS])
|
|
1032
|
+
.superRefine((hosts, ctx) => {
|
|
1033
|
+
hosts.forEach((h, i) => {
|
|
1034
|
+
for (const message of validateAllowHost(h)) {
|
|
1035
|
+
ctx.addIssue({ code: "custom", path: [i], message: `${h}: ${message}` });
|
|
1036
|
+
}
|
|
1037
|
+
});
|
|
1038
|
+
})
|
|
1039
|
+
.meta(meta({
|
|
1040
|
+
description: "Hosts sandboxes may reach when egress is allowlist: lowercase hostnames, optional leading '*.', no IPs, ports or internal-only names; applies to sandboxes created after the change",
|
|
1041
|
+
})),
|
|
1042
|
+
})
|
|
1043
|
+
.prefault({}),
|
|
1044
|
+
})
|
|
1045
|
+
.prefault({}),
|
|
1046
|
+
evals: z
|
|
1047
|
+
.object({
|
|
1048
|
+
orgConcurrency: z
|
|
1049
|
+
.number()
|
|
1050
|
+
.int()
|
|
1051
|
+
.positive()
|
|
1052
|
+
.default(2)
|
|
1053
|
+
.meta(meta({
|
|
1054
|
+
hot: true,
|
|
1055
|
+
description: "Maximum eval cases executing concurrently per organization across all replicas",
|
|
1056
|
+
})),
|
|
1057
|
+
workerConcurrency: z
|
|
1058
|
+
.number()
|
|
1059
|
+
.int()
|
|
1060
|
+
.positive()
|
|
1061
|
+
.default(4)
|
|
1062
|
+
.meta(meta({ description: "Eval case jobs one replica processes at the same time" })),
|
|
1063
|
+
defaultTokenCap: z
|
|
1064
|
+
.number()
|
|
1065
|
+
.int()
|
|
1066
|
+
.positive()
|
|
1067
|
+
.default(1_000_000)
|
|
1068
|
+
.meta(meta({
|
|
1069
|
+
description: "Token cap of an eval run when none is given; the run stops sending new model requests once it is reached",
|
|
1070
|
+
})),
|
|
1071
|
+
maxTokenCap: z
|
|
1072
|
+
.number()
|
|
1073
|
+
.int()
|
|
1074
|
+
.positive()
|
|
1075
|
+
.default(20_000_000)
|
|
1076
|
+
.meta(meta({ description: "Largest token cap an eval run may ask for" })),
|
|
1077
|
+
maxCasesPerSet: z
|
|
1078
|
+
.number()
|
|
1079
|
+
.int()
|
|
1080
|
+
.positive()
|
|
1081
|
+
.default(500)
|
|
1082
|
+
.meta(meta({ description: "Maximum number of cases in one eval set" })),
|
|
1083
|
+
maxCaseBytes: z
|
|
1084
|
+
.number()
|
|
1085
|
+
.int()
|
|
1086
|
+
.positive()
|
|
1087
|
+
.default(4_194_304)
|
|
1088
|
+
.meta(meta({
|
|
1089
|
+
description: "Largest log snapshot in bytes (serialized JSON) one eval case may store; larger runs cannot be added",
|
|
1090
|
+
})),
|
|
1091
|
+
judgeMaxOutputTokens: z
|
|
1092
|
+
.number()
|
|
1093
|
+
.int()
|
|
1094
|
+
.positive()
|
|
1095
|
+
.default(1024)
|
|
1096
|
+
.meta(meta({ description: "Maximum output tokens of one LLM judge request" })),
|
|
1097
|
+
maxConsecutiveErrors: z
|
|
1098
|
+
.number()
|
|
1099
|
+
.int()
|
|
1100
|
+
.positive()
|
|
1101
|
+
.default(10)
|
|
1102
|
+
.meta(meta({
|
|
1103
|
+
description: "Consecutive failed results after which an eval run is marked failed and its remaining cases are skipped",
|
|
1104
|
+
})),
|
|
1105
|
+
})
|
|
1106
|
+
// 默认上限必须在允许范围内,否则不传 tokenCap 的运行一律被拒
|
|
1107
|
+
.refine((c) => c.defaultTokenCap <= c.maxTokenCap, {
|
|
1108
|
+
message: "evals.defaultTokenCap must be at most evals.maxTokenCap",
|
|
1109
|
+
path: ["defaultTokenCap"],
|
|
1110
|
+
})
|
|
1111
|
+
.prefault({}),
|
|
1112
|
+
hooks: z
|
|
1113
|
+
.object({
|
|
1114
|
+
timeoutMs: z
|
|
1115
|
+
.number()
|
|
1116
|
+
.int()
|
|
1117
|
+
.positive()
|
|
1118
|
+
.max(60_000)
|
|
1119
|
+
.default(5000)
|
|
1120
|
+
.meta(meta({
|
|
1121
|
+
hot: true,
|
|
1122
|
+
description: "Time limit in milliseconds for one extension hook call; a policy hook that exceeds it denies the call, an observe hook is skipped",
|
|
1123
|
+
})),
|
|
1124
|
+
usageReportConcurrency: z
|
|
1125
|
+
.number()
|
|
1126
|
+
.int()
|
|
1127
|
+
.positive()
|
|
1128
|
+
.default(16)
|
|
1129
|
+
.meta(meta({
|
|
1130
|
+
description: "usage.report delivery jobs one worker replica processes at the same time",
|
|
1131
|
+
})),
|
|
1132
|
+
usageReportKeepHours: z
|
|
1133
|
+
.number()
|
|
1134
|
+
.int()
|
|
1135
|
+
.min(1)
|
|
1136
|
+
.max(720)
|
|
1137
|
+
.default(24)
|
|
1138
|
+
.meta(meta({
|
|
1139
|
+
description: "Hours a finished usage.report job is kept in Redis so re-enqueueing the same usage event (resumed step, sweeper) is deduplicated; at least 1, well above the sweeper's 10-minute overlap",
|
|
1140
|
+
})),
|
|
1141
|
+
})
|
|
1142
|
+
.prefault({}),
|
|
1143
|
+
log: z
|
|
1144
|
+
.object({
|
|
1145
|
+
level: z
|
|
1146
|
+
.enum(LOG_LEVELS)
|
|
1147
|
+
.default("info")
|
|
1148
|
+
.meta(meta({ hot: true, description: "Log level" })),
|
|
1149
|
+
})
|
|
1150
|
+
.default({ level: "info" }),
|
|
1151
|
+
});
|