@capybara-hq/kernel 0.0.0-stage → 0.1.0-rc.1
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 +26 -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 +1126 -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 +237 -0
- package/dist/config/schema.js +1192 -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 +423 -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 +151 -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 +211 -0
- package/dist/errors.js +213 -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 +790 -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 +176 -0
- package/dist/extensions/bootstrap.js +535 -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 +220 -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 +69 -0
- package/dist/index.js +67 -0
- package/dist/kernel.d.ts +259 -0
- package/dist/kernel.js +1326 -0
- package/dist/log-config.d.ts +9 -0
- package/dist/log-config.js +27 -0
- package/dist/log-context.d.ts +32 -0
- package/dist/log-context.js +40 -0
- package/dist/log-loki.d.ts +34 -0
- package/dist/log-loki.js +145 -0
- package/dist/log.d.ts +79 -0
- package/dist/log.js +303 -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 +272 -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 +148 -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 +806 -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 +551 -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 +116 -0
- package/dist/tools/builtins/sandbox/common.js +306 -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 +69 -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,266 @@
|
|
|
1
|
+
import { validateInputForm } from "@capybara-hq/plugin-sdk";
|
|
2
|
+
import { contentHash } from "./registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* MCP elicitation(D4,仿 Claude Code:表单 + URL 两种模式)映射到通用输入请求(Task 9 的 `InputRequired`)。
|
|
5
|
+
*
|
|
6
|
+
* 设计(为什么不是「真正挂起」):官方 SDK 的 elicitation 答复只能在原 `tools/call` 还挂着时送回同一个会话;
|
|
7
|
+
* 而内核等人回答时运行会暂停、worker 释放、连接器会话关闭(多副本下续跑可能在另一副本),原调用不可能保持。
|
|
8
|
+
* 所以采用「可续的连接器调用」:
|
|
9
|
+
*
|
|
10
|
+
* 1. 调用途中远端发起 elicitation → 连接器调用 `onElicit` → 本会话({@link ElicitationSession})把请求映射成
|
|
11
|
+
* `InputForm`,记下待问的表单与 state,并**中止本次调用**(`onSuspend`,经 `callTool` 的 signal),`onElicit` 以
|
|
12
|
+
* {@link ElicitationSuspended} 拒绝;管线据此
|
|
13
|
+
* 把这次执行当作 `input_required`(写 `question_asked`、运行进入等待)。
|
|
14
|
+
* 2. 用户回答(或超时 / 取消)后,管线照常用同一 input 再次调用该工具,带 `ctx.resume = { state, answer }`;
|
|
15
|
+
* 远端再次发起**同样的** elicitation(按指纹匹配:表单模式看 `requestedSchema` 与文案,URL 模式看地址的 origin + path 与文案)
|
|
16
|
+
* 时,本会话立即用用户的答案答复,远端继续执行。一次调用里有多个 elicitation 时,state 带上之前的全部答复,
|
|
17
|
+
* 每次续跑整条重放;最多 3 轮(管线的输入轮次上限)。
|
|
18
|
+
*
|
|
19
|
+
* 限制(写进报告与 .agents/skills/writing-tools):远端第二次没有发起同样的 elicitation(换了 schema / 不再问)时,答案
|
|
20
|
+
* 不会被使用——前者会再问一次用户,后者远端按自己的逻辑继续;远端在 elicitation 之前做过的副作用会随重新发起
|
|
21
|
+
* 的调用再做一次(大多数服务在动手之前先问);URL 模式的完成通知(`notifications/elicitation/complete`)收不到
|
|
22
|
+
* (会话已关闭),以用户在卡片上确认「已完成」为准。
|
|
23
|
+
*
|
|
24
|
+
* 超出 InputForm 子集的表单(嵌套对象、`minLength > 1`、`minItems > 1` 等)不展示:立即答复 `decline`,并在工具
|
|
25
|
+
* 结果末尾附一条给模型的英文说明。
|
|
26
|
+
*/
|
|
27
|
+
/** 本次调用为问用户而被中止(`onElicit` 以它拒绝;管线按 pending 的输入请求处理,不当作失败)。 */
|
|
28
|
+
export class ElicitationSuspended extends Error {
|
|
29
|
+
constructor() {
|
|
30
|
+
super("The call was suspended to ask the user for input");
|
|
31
|
+
this.name = "ElicitationSuspended";
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/** 不能展示的 elicitation 被拒绝时附在工具结果后的说明(模型可见,英文)。 */
|
|
35
|
+
export const UNSUPPORTED_ELICITATION_NOTE = "The app asked the user for input that cannot be shown in this client, so the request was declined";
|
|
36
|
+
const unsupportedNote = (why) => `[${UNSUPPORTED_ELICITATION_NOTE} (${why}). If the call needs that input, ask the user for it with ask_user and pass it as tool arguments, or try another approach.]`;
|
|
37
|
+
/** URL 模式表单里「已完成」开关的字段名。 */
|
|
38
|
+
export const URL_COMPLETED_FIELD = "completed";
|
|
39
|
+
/** 表单标题(远端给的 message)最多字符数。 */
|
|
40
|
+
const MAX_TITLE = 2000;
|
|
41
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
42
|
+
const str = (v) => typeof v === "string" && v.trim() !== "" ? v : undefined;
|
|
43
|
+
/** 一个属性 → 表单字段;超出子集返回原因。 */
|
|
44
|
+
function fieldFor(key, p, required) {
|
|
45
|
+
const at = `field "${key}"`;
|
|
46
|
+
if (!isObj(p))
|
|
47
|
+
return `${at} is not an object schema`;
|
|
48
|
+
const label = str(p.title) ?? key;
|
|
49
|
+
const notes = [];
|
|
50
|
+
const description = str(p.description);
|
|
51
|
+
if (description !== undefined)
|
|
52
|
+
notes.push(description);
|
|
53
|
+
let schema;
|
|
54
|
+
let multiSelect = false;
|
|
55
|
+
switch (p.type) {
|
|
56
|
+
case "string": {
|
|
57
|
+
if (typeof p.minLength === "number" && p.minLength > 1)
|
|
58
|
+
return `${at} uses minLength`;
|
|
59
|
+
if (Array.isArray(p.enum)) {
|
|
60
|
+
const values = p.enum.filter((x) => typeof x === "string");
|
|
61
|
+
if (values.length !== p.enum.length || values.length === 0)
|
|
62
|
+
return `${at} has a non-string enum`;
|
|
63
|
+
const names = Array.isArray(p.enumNames) ? p.enumNames : undefined;
|
|
64
|
+
if (names && names.length === values.length && names.every((n) => typeof n === "string")) {
|
|
65
|
+
notes.push(`Options: ${values.map((v, i) => `${v} = ${names[i]}`).join("; ")}.`);
|
|
66
|
+
}
|
|
67
|
+
schema = { type: "string", enum: values };
|
|
68
|
+
}
|
|
69
|
+
else if (Array.isArray(p.oneOf)) {
|
|
70
|
+
const opts = p.oneOf.filter((o) => isObj(o) && typeof o.const === "string");
|
|
71
|
+
if (opts.length !== p.oneOf.length || opts.length === 0)
|
|
72
|
+
return `${at} has unsupported oneOf`;
|
|
73
|
+
notes.push(`Options: ${opts.map((o) => `${o.const} = ${str(o.title) ?? o.const}`).join("; ")}.`);
|
|
74
|
+
schema = { type: "string", enum: opts.map((o) => o.const) };
|
|
75
|
+
}
|
|
76
|
+
else {
|
|
77
|
+
if (typeof p.format === "string")
|
|
78
|
+
notes.push(`Format: ${p.format}.`);
|
|
79
|
+
schema =
|
|
80
|
+
typeof p.maxLength === "number" && Number.isInteger(p.maxLength) && p.maxLength >= 0
|
|
81
|
+
? { type: "string", maxLength: p.maxLength }
|
|
82
|
+
: { type: "string" };
|
|
83
|
+
}
|
|
84
|
+
break;
|
|
85
|
+
}
|
|
86
|
+
case "boolean":
|
|
87
|
+
schema = { type: "boolean" };
|
|
88
|
+
break;
|
|
89
|
+
case "number":
|
|
90
|
+
case "integer": {
|
|
91
|
+
const s = {
|
|
92
|
+
type: p.type,
|
|
93
|
+
};
|
|
94
|
+
if (typeof p.minimum === "number" && Number.isFinite(p.minimum))
|
|
95
|
+
s.minimum = p.minimum;
|
|
96
|
+
if (typeof p.maximum === "number" && Number.isFinite(p.maximum))
|
|
97
|
+
s.maximum = p.maximum;
|
|
98
|
+
schema = s;
|
|
99
|
+
break;
|
|
100
|
+
}
|
|
101
|
+
case "array": {
|
|
102
|
+
const items = isObj(p.items) ? p.items : undefined;
|
|
103
|
+
let values;
|
|
104
|
+
if (items && Array.isArray(items.enum)) {
|
|
105
|
+
values = items.enum.filter((x) => typeof x === "string");
|
|
106
|
+
if (values.length !== items.enum.length)
|
|
107
|
+
values = undefined;
|
|
108
|
+
}
|
|
109
|
+
else if (items && Array.isArray(items.anyOf)) {
|
|
110
|
+
const opts = items.anyOf.filter((o) => isObj(o) && typeof o.const === "string");
|
|
111
|
+
if (opts.length === items.anyOf.length) {
|
|
112
|
+
values = opts.map((o) => o.const);
|
|
113
|
+
notes.push(`Options: ${opts.map((o) => `${o.const} = ${str(o.title) ?? o.const}`).join("; ")}.`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!values || values.length === 0)
|
|
117
|
+
return `${at} is an array without string options`;
|
|
118
|
+
if (typeof p.minItems === "number" && p.minItems > 1)
|
|
119
|
+
return `${at} uses minItems`;
|
|
120
|
+
if (typeof p.maxItems === "number" && p.maxItems < values.length)
|
|
121
|
+
return `${at} uses maxItems`;
|
|
122
|
+
schema = { type: "string", enum: values };
|
|
123
|
+
multiSelect = true;
|
|
124
|
+
break;
|
|
125
|
+
}
|
|
126
|
+
default:
|
|
127
|
+
return `${at} has unsupported type ${JSON.stringify(p.type)}`;
|
|
128
|
+
}
|
|
129
|
+
if (p.default !== undefined && !multiSelect && !("enum" in schema)) {
|
|
130
|
+
notes.push(`Default: ${JSON.stringify(p.default)}.`);
|
|
131
|
+
}
|
|
132
|
+
return {
|
|
133
|
+
key,
|
|
134
|
+
label,
|
|
135
|
+
...(notes.length > 0 && { description: notes.join(" ") }),
|
|
136
|
+
schema,
|
|
137
|
+
...(multiSelect && { multiSelect: true }),
|
|
138
|
+
...(required && { required: true }),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/** elicitation → 交互表单;超出子集 → `{ unsupported: 原因 }`(英文)。 */
|
|
142
|
+
export function elicitationForm(req) {
|
|
143
|
+
const title = req.message.trim().slice(0, MAX_TITLE) || "Input requested";
|
|
144
|
+
let form;
|
|
145
|
+
if (req.mode === "url") {
|
|
146
|
+
form = {
|
|
147
|
+
title,
|
|
148
|
+
url: req.url,
|
|
149
|
+
fields: [
|
|
150
|
+
{
|
|
151
|
+
key: URL_COMPLETED_FIELD,
|
|
152
|
+
label: { en: "I have completed this step", zh: "我已完成这一步" },
|
|
153
|
+
schema: { type: "boolean" },
|
|
154
|
+
required: true,
|
|
155
|
+
},
|
|
156
|
+
],
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
const s = req.requestedSchema;
|
|
161
|
+
if (s.type !== "object" || !isObj(s.properties)) {
|
|
162
|
+
return { unsupported: "requestedSchema is not an object schema with properties" };
|
|
163
|
+
}
|
|
164
|
+
const required = new Set(Array.isArray(s.required) ? s.required : []);
|
|
165
|
+
const fields = [];
|
|
166
|
+
for (const [key, p] of Object.entries(s.properties)) {
|
|
167
|
+
const f = fieldFor(key, p, required.has(key));
|
|
168
|
+
if (typeof f === "string")
|
|
169
|
+
return { unsupported: f };
|
|
170
|
+
fields.push(f);
|
|
171
|
+
}
|
|
172
|
+
if (fields.length === 0)
|
|
173
|
+
return { unsupported: "the form has no fields" };
|
|
174
|
+
form = { title, fields };
|
|
175
|
+
}
|
|
176
|
+
const problems = validateInputForm(form);
|
|
177
|
+
return problems.length > 0 ? { unsupported: problems.join("; ") } : { form };
|
|
178
|
+
}
|
|
179
|
+
/** 指纹:表单模式按 requestedSchema,URL 模式按地址的 origin + path(query 常带一次性 state)。 */
|
|
180
|
+
function fingerprint(req) {
|
|
181
|
+
// 文案也计入:同一 schema 换了说明(问的是另一件事)要重新问用户
|
|
182
|
+
const message = contentHash(req.message);
|
|
183
|
+
if (req.mode === "form") {
|
|
184
|
+
return contentHash({ mode: "form", schema: req.requestedSchema, message });
|
|
185
|
+
}
|
|
186
|
+
let target = req.url;
|
|
187
|
+
try {
|
|
188
|
+
const u = new URL(req.url);
|
|
189
|
+
target = `${u.origin}${u.pathname}`;
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
// 原样
|
|
193
|
+
}
|
|
194
|
+
return contentHash({ mode: "url", target, message });
|
|
195
|
+
}
|
|
196
|
+
/** 用户答案 → 给远端的答复。 */
|
|
197
|
+
function responseFor(mode, answer) {
|
|
198
|
+
if (answer === null)
|
|
199
|
+
return { action: "cancel" };
|
|
200
|
+
if (mode === "url") {
|
|
201
|
+
return answer[URL_COMPLETED_FIELD] === true ? { action: "accept" } : { action: "decline" };
|
|
202
|
+
}
|
|
203
|
+
return { action: "accept", content: answer };
|
|
204
|
+
}
|
|
205
|
+
function parseState(state) {
|
|
206
|
+
const e = isObj(state) ? state.elicitation : undefined;
|
|
207
|
+
if (!isObj(e) || !Array.isArray(e.answers) || !isObj(e.pending))
|
|
208
|
+
return undefined;
|
|
209
|
+
const p = e.pending;
|
|
210
|
+
if (typeof p.fp !== "string" || (p.mode !== "form" && p.mode !== "url"))
|
|
211
|
+
return undefined;
|
|
212
|
+
const answers = e.answers.filter((a) => isObj(a) && typeof a.fp === "string" && isObj(a.response));
|
|
213
|
+
return { answers, pending: { fp: p.fp, mode: p.mode } };
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 一次连接器工具调用里的 elicitation 处理(见文件头)。`onSuspend` 中止本次调用;`declineAll` 用于不能续跑的场景
|
|
217
|
+
* (如 resources 工具),一律拒绝并附说明。
|
|
218
|
+
*/
|
|
219
|
+
export class ElicitationSession {
|
|
220
|
+
opts;
|
|
221
|
+
/** 需要问用户的表单与 state(有值即本次执行按 `input_required` 处理)。 */
|
|
222
|
+
pending;
|
|
223
|
+
/** 附在工具结果后给模型的说明。 */
|
|
224
|
+
notes = [];
|
|
225
|
+
answers;
|
|
226
|
+
used = new Set();
|
|
227
|
+
constructor(opts) {
|
|
228
|
+
this.opts = opts;
|
|
229
|
+
const prev = opts.resume ? parseState(opts.resume.state) : undefined;
|
|
230
|
+
this.answers = prev
|
|
231
|
+
? [
|
|
232
|
+
...prev.answers,
|
|
233
|
+
{
|
|
234
|
+
fp: prev.pending.fp,
|
|
235
|
+
response: responseFor(prev.pending.mode, opts.resume?.answer ?? null),
|
|
236
|
+
},
|
|
237
|
+
]
|
|
238
|
+
: [];
|
|
239
|
+
}
|
|
240
|
+
handle = async (req) => {
|
|
241
|
+
if (this.opts.declineAll) {
|
|
242
|
+
this.notes.push(unsupportedNote("this tool cannot pause for user input"));
|
|
243
|
+
return { action: "decline" };
|
|
244
|
+
}
|
|
245
|
+
const fp = fingerprint(req);
|
|
246
|
+
const i = this.answers.findIndex((a, idx) => a.fp === fp && !this.used.has(idx));
|
|
247
|
+
if (i >= 0) {
|
|
248
|
+
this.used.add(i);
|
|
249
|
+
return this.answers[i].response;
|
|
250
|
+
}
|
|
251
|
+
const mapped = elicitationForm(req);
|
|
252
|
+
if ("unsupported" in mapped) {
|
|
253
|
+
this.notes.push(unsupportedNote(mapped.unsupported));
|
|
254
|
+
return { action: "decline" };
|
|
255
|
+
}
|
|
256
|
+
if (!this.pending) {
|
|
257
|
+
this.pending = {
|
|
258
|
+
form: mapped.form,
|
|
259
|
+
state: { elicitation: { answers: this.answers, pending: { fp, mode: req.mode } } },
|
|
260
|
+
};
|
|
261
|
+
this.opts.onSuspend();
|
|
262
|
+
}
|
|
263
|
+
// 调用已被中止:以错误结束(不让连接器等一个永不答复的 promise,如 -32042 路径里的 await),会话随后关闭
|
|
264
|
+
throw new ElicitationSuspended();
|
|
265
|
+
};
|
|
266
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The query parameter names of `u` that look like a credential (each once, in URL order). */
|
|
2
|
+
export declare const credentialQueryParams: (u: URL) => string[];
|
|
3
|
+
/** 端点里凭据样式的头 / query 参数 / URL 用户信息;path 相对 `endpoint`。 */
|
|
4
|
+
export declare function endpointCredentialIssues(endpoint: unknown): {
|
|
5
|
+
path: string;
|
|
6
|
+
message: string;
|
|
7
|
+
}[];
|
|
8
|
+
/**
|
|
9
|
+
* 给没有 `connectors.manage` 的人看的端点:URL 字段(`url` / `*Url`)只留源(scheme + host + port),有路径时打码为
|
|
10
|
+
* `<origin>/…`(去掉路径、query、fragment 与用户信息);`headers` 只留头名(`headerNames`)。
|
|
11
|
+
* 路径、固定头值与 query 可能含租户号等管理员不想公开的信息。
|
|
12
|
+
*/
|
|
13
|
+
export declare function publicEndpoint(endpoint: unknown): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* 连接器列表 / 详情里给所有人看的端点(Ruling A21):`text` / `*Text` 字段(如最大 2 MB 的 OpenAPI 文档)不回显全文,
|
|
16
|
+
* 换成 `<field>Bytes`(UTF-8 字节数)与 `<field>Sha256`;要改文档时管理员重新上传。存储与连接器拿到的仍是全文。
|
|
17
|
+
*/
|
|
18
|
+
export declare function endpointView(endpoint: unknown): unknown;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
/**
|
|
3
|
+
* 连接器端点的通用处理(与连接器无关,按约定:顶层名为 `url` 或以 `Url` 结尾的字符串字段是 URL,如 MCP 的 `url`、
|
|
4
|
+
* OpenAPI 的 `specUrl` / `baseUrl`;`headers` 是固定头):端点配置对 `connectors.use` 的成员可见,
|
|
5
|
+
* 不能放凭据——凭据走连接器的认证设置(加密存储、按调用注入、结果打码)。
|
|
6
|
+
*/
|
|
7
|
+
/** 端点里按「大段文本」处理的顶层字段名(如 OpenAPI 的 `specText`):连接器视图只给字节数与 sha256。 */
|
|
8
|
+
const isTextField = (key) => key === "text" || /^[a-z][A-Za-z0-9]*Text$/.test(key);
|
|
9
|
+
/** 端点里按 URL 处理的顶层字段名。 */
|
|
10
|
+
const isUrlField = (key) => key === "url" || /^[a-z][A-Za-z0-9]*Url$/.test(key);
|
|
11
|
+
const isObj = (v) => typeof v === "object" && v !== null && !Array.isArray(v);
|
|
12
|
+
/** 凭据样式的头名(小写比较):authorization 各变体、api key、token、secret、cookie。 */
|
|
13
|
+
const CREDENTIAL_HEADER = /^(?:(?:proxy-)?authorization|x-authorization|cookie|(?:x-)?api-?key|x-auth-token|.*-token|.*-secret)$/;
|
|
14
|
+
/** 凭据样式的 query 参数名(小写比较)。 */
|
|
15
|
+
const CREDENTIAL_QUERY = new Set([
|
|
16
|
+
"key",
|
|
17
|
+
"api_key",
|
|
18
|
+
"apikey",
|
|
19
|
+
"api-key",
|
|
20
|
+
"token",
|
|
21
|
+
"access_token",
|
|
22
|
+
"secret",
|
|
23
|
+
]);
|
|
24
|
+
/** The query parameter names of `u` that look like a credential (each once, in URL order). */
|
|
25
|
+
export const credentialQueryParams = (u) => [...new Set([...u.searchParams.keys()])].filter((k) => CREDENTIAL_QUERY.has(k.toLowerCase()));
|
|
26
|
+
const USE_CREDENTIALS = "configure it in the connector's credential settings instead";
|
|
27
|
+
/** 端点里凭据样式的头 / query 参数 / URL 用户信息;path 相对 `endpoint`。 */
|
|
28
|
+
export function endpointCredentialIssues(endpoint) {
|
|
29
|
+
if (!isObj(endpoint))
|
|
30
|
+
return [];
|
|
31
|
+
const out = [];
|
|
32
|
+
if (isObj(endpoint.headers)) {
|
|
33
|
+
for (const name of Object.keys(endpoint.headers)) {
|
|
34
|
+
if (CREDENTIAL_HEADER.test(name.toLowerCase())) {
|
|
35
|
+
out.push({
|
|
36
|
+
path: `endpoint.headers.${name}`,
|
|
37
|
+
message: `Header "${name}" looks like a credential; ${USE_CREDENTIALS}`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
for (const [field, value] of Object.entries(endpoint)) {
|
|
43
|
+
if (!isUrlField(field) || typeof value !== "string")
|
|
44
|
+
continue;
|
|
45
|
+
let u;
|
|
46
|
+
try {
|
|
47
|
+
u = new URL(value);
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
u = undefined; // 格式错误交给连接器的 schema
|
|
51
|
+
}
|
|
52
|
+
if (!u)
|
|
53
|
+
continue;
|
|
54
|
+
if (u.username !== "" || u.password !== "") {
|
|
55
|
+
out.push({
|
|
56
|
+
path: `endpoint.${field}`,
|
|
57
|
+
message: `The URL must not contain a user name or password; ${USE_CREDENTIALS}`,
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const bad = credentialQueryParams(u);
|
|
61
|
+
if (bad.length > 0) {
|
|
62
|
+
out.push({
|
|
63
|
+
path: `endpoint.${field}`,
|
|
64
|
+
message: `Query parameter ${bad.map((k) => `"${k}"`).join(", ")} looks like a credential; ${USE_CREDENTIALS}`,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* 给没有 `connectors.manage` 的人看的端点:URL 字段(`url` / `*Url`)只留源(scheme + host + port),有路径时打码为
|
|
72
|
+
* `<origin>/…`(去掉路径、query、fragment 与用户信息);`headers` 只留头名(`headerNames`)。
|
|
73
|
+
* 路径、固定头值与 query 可能含租户号等管理员不想公开的信息。
|
|
74
|
+
*/
|
|
75
|
+
export function publicEndpoint(endpoint) {
|
|
76
|
+
if (!isObj(endpoint))
|
|
77
|
+
return endpoint;
|
|
78
|
+
const { headers, ...rest } = endpoint;
|
|
79
|
+
const out = {};
|
|
80
|
+
for (const [field, value] of Object.entries(rest)) {
|
|
81
|
+
if (!isUrlField(field) || typeof value !== "string") {
|
|
82
|
+
out[field] = value;
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
try {
|
|
86
|
+
const u = new URL(value);
|
|
87
|
+
out[field] = u.pathname === "/" || u.pathname === "" ? u.origin : `${u.origin}/…`;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// 不是合法 URL:不展示
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (isObj(headers))
|
|
94
|
+
out.headerNames = Object.keys(headers);
|
|
95
|
+
return out;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* 连接器列表 / 详情里给所有人看的端点(Ruling A21):`text` / `*Text` 字段(如最大 2 MB 的 OpenAPI 文档)不回显全文,
|
|
99
|
+
* 换成 `<field>Bytes`(UTF-8 字节数)与 `<field>Sha256`;要改文档时管理员重新上传。存储与连接器拿到的仍是全文。
|
|
100
|
+
*/
|
|
101
|
+
export function endpointView(endpoint) {
|
|
102
|
+
if (!isObj(endpoint))
|
|
103
|
+
return endpoint;
|
|
104
|
+
const out = {};
|
|
105
|
+
for (const [field, value] of Object.entries(endpoint)) {
|
|
106
|
+
if (isTextField(field) && typeof value === "string") {
|
|
107
|
+
out[`${field}Bytes`] = Buffer.byteLength(value, "utf8");
|
|
108
|
+
out[`${field}Sha256`] = createHash("sha256").update(value).digest("hex");
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
out[field] = value;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return out;
|
|
115
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import type { KernelDb } from "../db/kernel-schema.js";
|
|
2
|
+
import type { ToolRegistry } from "./registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* Tool presentation metadata for the conversation page (UI refresh B, design spec §6.16.9): the
|
|
5
|
+
* kind picks the row verb and the group counts, the title and key arguments the row's wording.
|
|
6
|
+
* Display only: nothing here reaches the model.
|
|
7
|
+
*/
|
|
8
|
+
export type ToolKind = "command" | "read" | "edit" | "search" | "connector" | "meta" | "tool";
|
|
9
|
+
export interface ToolInfo {
|
|
10
|
+
/** The model-visible tool key, as asked for. */
|
|
11
|
+
key: string;
|
|
12
|
+
/** The declared display title (`ToolSpec.title`), or null. */
|
|
13
|
+
title: string | null;
|
|
14
|
+
kind: ToolKind;
|
|
15
|
+
/** The declared key arguments (`ToolSpec.keyArgs`), or []. */
|
|
16
|
+
keyArgs: string[];
|
|
17
|
+
source: {
|
|
18
|
+
kind: "builtin";
|
|
19
|
+
} | {
|
|
20
|
+
kind: "extension";
|
|
21
|
+
name: string;
|
|
22
|
+
} | {
|
|
23
|
+
kind: "connector";
|
|
24
|
+
id: string;
|
|
25
|
+
name: string;
|
|
26
|
+
}
|
|
27
|
+
/** No tool with this key exists now (removed connector, unloaded extension, …). */
|
|
28
|
+
| {
|
|
29
|
+
kind: "unknown";
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
/** Kinds of the kernel builtin tools; a builtin missing here is a plain `tool`. */
|
|
33
|
+
export declare const BUILTIN_TOOL_KINDS: Readonly<Record<string, ToolKind>>;
|
|
34
|
+
/** At most this many keys per request, each at most {@link TOOL_INFO_KEY_MAX} characters. */
|
|
35
|
+
export declare const TOOL_INFO_MAX_KEYS = 100;
|
|
36
|
+
export declare const TOOL_INFO_KEY_MAX = 200;
|
|
37
|
+
export interface ToolInfoDeps {
|
|
38
|
+
db: KernelDb;
|
|
39
|
+
registry: Pick<ToolRegistry, "builtinSpecs" | "extensionToolSpecs">;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Presentation metadata for `keys` in this org, in request order with repeats dropped. Builtins
|
|
43
|
+
* by name; `<prefix>__<tool>` keys first as a loaded extension's registration, then as a live
|
|
44
|
+
* connector's current stored tool (its reviewed definition, never a pending one). Anything else
|
|
45
|
+
* comes back as an unknown plain tool.
|
|
46
|
+
*
|
|
47
|
+
* - Titles and key arguments are never read from `tool_specs`: it is content-addressed by
|
|
48
|
+
* `specHash`, which leaves the display fields out, so it keeps whichever title was stored first
|
|
49
|
+
* under a hash. Eval and trajectory viewers must not show a title from it either.
|
|
50
|
+
* - Extension tools resolve deployment-wide (from the loaded host), not per org: a tool of an
|
|
51
|
+
* extension that is not enabled in this org still answers `source: extension` with its title.
|
|
52
|
+
* That is deliberate: old conversation logs keep their labels, and the data is not sensitive.
|
|
53
|
+
* - A key whose prefix is both a loaded extension's name and a connector slug resolves to the
|
|
54
|
+
* extension. When an agent's tools are built, the registry's `claim()` reports that collision;
|
|
55
|
+
* here it only changes the label.
|
|
56
|
+
*/
|
|
57
|
+
export declare function toolInfo(deps: ToolInfoDeps, orgId: string, keys: readonly string[]): Promise<ToolInfo[]>;
|
|
58
|
+
export interface ConversationToolInfoDeps extends ToolInfoDeps {
|
|
59
|
+
/** Conversation visibility (the same rule as the events API: `ConversationsService.isAccessible`). */
|
|
60
|
+
isAccessible(orgId: string, conversationId: string, viewerAccountId: string): Promise<boolean>;
|
|
61
|
+
}
|
|
62
|
+
/** `GET /conversations/:id/tools`: {@link toolInfo} for a conversation the viewer can read. */
|
|
63
|
+
export declare class ConversationToolInfo {
|
|
64
|
+
private readonly d;
|
|
65
|
+
constructor(d: ConversationToolInfoDeps);
|
|
66
|
+
get(orgId: string, conversationId: string, viewerAccountId: string, keys: readonly string[]): Promise<ToolInfo[]>;
|
|
67
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { ApiError } from "../errors.js";
|
|
2
|
+
import { UUID_RE } from "../ui/registry.js";
|
|
3
|
+
import { KEY_SEPARATOR, toolKey } from "./naming.js";
|
|
4
|
+
/** Kinds of the kernel builtin tools; a builtin missing here is a plain `tool`. */
|
|
5
|
+
export const BUILTIN_TOOL_KINDS = {
|
|
6
|
+
sandbox_bash: "command",
|
|
7
|
+
sandbox_read: "read",
|
|
8
|
+
sandbox_write: "edit",
|
|
9
|
+
sandbox_edit: "edit",
|
|
10
|
+
sandbox_glob: "search",
|
|
11
|
+
sandbox_grep: "search",
|
|
12
|
+
sandbox_deliver: "tool",
|
|
13
|
+
tool_search: "meta",
|
|
14
|
+
skill_load: "meta",
|
|
15
|
+
skill_write: "meta",
|
|
16
|
+
read_tool_output: "meta",
|
|
17
|
+
ask_user: "meta",
|
|
18
|
+
};
|
|
19
|
+
/** At most this many keys per request, each at most {@link TOOL_INFO_KEY_MAX} characters. */
|
|
20
|
+
export const TOOL_INFO_MAX_KEYS = 100;
|
|
21
|
+
export const TOOL_INFO_KEY_MAX = 200;
|
|
22
|
+
const display = (spec) => ({
|
|
23
|
+
title: typeof spec?.title === "string" ? spec.title : null,
|
|
24
|
+
keyArgs: Array.isArray(spec?.keyArgs) ? [...spec.keyArgs] : [],
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Presentation metadata for `keys` in this org, in request order with repeats dropped. Builtins
|
|
28
|
+
* by name; `<prefix>__<tool>` keys first as a loaded extension's registration, then as a live
|
|
29
|
+
* connector's current stored tool (its reviewed definition, never a pending one). Anything else
|
|
30
|
+
* comes back as an unknown plain tool.
|
|
31
|
+
*
|
|
32
|
+
* - Titles and key arguments are never read from `tool_specs`: it is content-addressed by
|
|
33
|
+
* `specHash`, which leaves the display fields out, so it keeps whichever title was stored first
|
|
34
|
+
* under a hash. Eval and trajectory viewers must not show a title from it either.
|
|
35
|
+
* - Extension tools resolve deployment-wide (from the loaded host), not per org: a tool of an
|
|
36
|
+
* extension that is not enabled in this org still answers `source: extension` with its title.
|
|
37
|
+
* That is deliberate: old conversation logs keep their labels, and the data is not sensitive.
|
|
38
|
+
* - A key whose prefix is both a loaded extension's name and a connector slug resolves to the
|
|
39
|
+
* extension. When an agent's tools are built, the registry's `claim()` reports that collision;
|
|
40
|
+
* here it only changes the label.
|
|
41
|
+
*/
|
|
42
|
+
export async function toolInfo(deps, orgId, keys) {
|
|
43
|
+
const unique = [...new Set(keys)];
|
|
44
|
+
const builtins = new Map(deps.registry.builtinSpecs().map((s) => [s.name, s]));
|
|
45
|
+
const extensions = new Map(deps.registry.extensionToolSpecs().map((t) => [toolKey(t.plugin, t.spec.name), t]));
|
|
46
|
+
const split = (key) => {
|
|
47
|
+
const i = key.indexOf(KEY_SEPARATOR);
|
|
48
|
+
return i > 0 ? [key.slice(0, i), key.slice(i + KEY_SEPARATOR.length)] : null;
|
|
49
|
+
};
|
|
50
|
+
const slugs = [
|
|
51
|
+
...new Set(unique.flatMap((k) => {
|
|
52
|
+
if (builtins.has(k) || extensions.has(k))
|
|
53
|
+
return [];
|
|
54
|
+
const p = split(k);
|
|
55
|
+
return p ? [p[0]] : [];
|
|
56
|
+
})),
|
|
57
|
+
];
|
|
58
|
+
const connectorRows = slugs.length === 0
|
|
59
|
+
? []
|
|
60
|
+
: await deps.db
|
|
61
|
+
.selectFrom("connectors as c")
|
|
62
|
+
.innerJoin("connector_tools as t", "t.connector_id", "c.id")
|
|
63
|
+
.select(["c.id", "c.slug", "c.name", "t.name as tool", "t.spec"])
|
|
64
|
+
.where("c.org_id", "=", orgId)
|
|
65
|
+
.where("c.deleted_at", "is", null)
|
|
66
|
+
.where("c.slug", "in", slugs)
|
|
67
|
+
.execute();
|
|
68
|
+
const connectorTools = new Map(connectorRows.map((r) => [toolKey(r.slug, r.tool), r]));
|
|
69
|
+
return unique.map((key) => {
|
|
70
|
+
const b = builtins.get(key);
|
|
71
|
+
if (b) {
|
|
72
|
+
return {
|
|
73
|
+
key,
|
|
74
|
+
...display(b),
|
|
75
|
+
kind: BUILTIN_TOOL_KINDS[key] ?? "tool",
|
|
76
|
+
source: { kind: "builtin" },
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
const e = extensions.get(key);
|
|
80
|
+
if (e)
|
|
81
|
+
return {
|
|
82
|
+
key,
|
|
83
|
+
...display(e.spec),
|
|
84
|
+
kind: "tool",
|
|
85
|
+
source: { kind: "extension", name: e.plugin },
|
|
86
|
+
};
|
|
87
|
+
const c = connectorTools.get(key);
|
|
88
|
+
if (c) {
|
|
89
|
+
// The reviewed definition: a pending (unreviewed) one never supplies display text.
|
|
90
|
+
return {
|
|
91
|
+
key,
|
|
92
|
+
...display(c.spec),
|
|
93
|
+
kind: "connector",
|
|
94
|
+
source: { kind: "connector", id: c.id, name: c.name },
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { key, title: null, kind: "tool", keyArgs: [], source: { kind: "unknown" } };
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
/** `GET /conversations/:id/tools`: {@link toolInfo} for a conversation the viewer can read. */
|
|
101
|
+
export class ConversationToolInfo {
|
|
102
|
+
d;
|
|
103
|
+
constructor(d) {
|
|
104
|
+
this.d = d;
|
|
105
|
+
}
|
|
106
|
+
async get(orgId, conversationId, viewerAccountId, keys) {
|
|
107
|
+
if (!UUID_RE.test(conversationId) ||
|
|
108
|
+
!(await this.d.isAccessible(orgId, conversationId, viewerAccountId))) {
|
|
109
|
+
throw new ApiError("conversation.not_found", "Conversation not found");
|
|
110
|
+
}
|
|
111
|
+
return toolInfo(this.d, orgId, keys);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具命名(Global Constraints):模型可见的工具 key 必须匹配 `^[a-zA-Z0-9_-]{1,64}$`;
|
|
3
|
+
* 插件工具为 `<plugin>__<tool>`,连接器工具为 `<connectorSlug>__<tool>`,内置工具就是其名字本身。
|
|
4
|
+
* 超长或含非法字符的 key 一律报出来,不截断、不猜。
|
|
5
|
+
*/
|
|
6
|
+
export declare const TOOL_KEY_RE: RegExp;
|
|
7
|
+
export declare const TOOL_KEY_MAX = 64;
|
|
8
|
+
/** 连接器 slug:小写字母开头,小写字母 / 数字 / 下划线,最长 24。 */
|
|
9
|
+
export declare const APP_SLUG_RE: RegExp;
|
|
10
|
+
/** 前缀与工具名之间的分隔符。 */
|
|
11
|
+
export declare const KEY_SEPARATOR = "__";
|
|
12
|
+
/**
|
|
13
|
+
* slug 是否合法:除正则外,不得含连续下划线、不得以下划线结尾——否则 `a__b` + `c` 与 `a` + `b__c`
|
|
14
|
+
* 会拼出同一个 key。
|
|
15
|
+
*/
|
|
16
|
+
export declare function isValidSlug(slug: string): boolean;
|
|
17
|
+
/** slug 不合法时的英文说明(给 validation_failed 用)。 */
|
|
18
|
+
export declare const SLUG_RULE = "Slug must start with a lowercase letter, contain only lowercase letters, digits and single underscores, not end with an underscore, and be at most 24 characters";
|
|
19
|
+
/**
|
|
20
|
+
* 由连接器名推导 slug:转小写,非 `[a-z0-9]` 的连续字符折成一个下划线,去掉首尾下划线与开头的数字 / 下划线,
|
|
21
|
+
* 截到 24 位(再去掉尾部下划线)。推导不出合法 slug(如名称全是中文)时返回 null,由调用方要求显式给出。
|
|
22
|
+
*/
|
|
23
|
+
export declare function deriveSlug(name: string): string | null;
|
|
24
|
+
/** 拼 `<prefix>__<name>`。 */
|
|
25
|
+
export declare function toolKey(prefix: string, name: string): string;
|
|
26
|
+
/** key 不合法时返回英文原因,合法时返回 null。 */
|
|
27
|
+
export declare function toolKeyIssue(key: string): string | null;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 工具命名(Global Constraints):模型可见的工具 key 必须匹配 `^[a-zA-Z0-9_-]{1,64}$`;
|
|
3
|
+
* 插件工具为 `<plugin>__<tool>`,连接器工具为 `<connectorSlug>__<tool>`,内置工具就是其名字本身。
|
|
4
|
+
* 超长或含非法字符的 key 一律报出来,不截断、不猜。
|
|
5
|
+
*/
|
|
6
|
+
export const TOOL_KEY_RE = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
7
|
+
export const TOOL_KEY_MAX = 64;
|
|
8
|
+
/** 连接器 slug:小写字母开头,小写字母 / 数字 / 下划线,最长 24。 */
|
|
9
|
+
export const APP_SLUG_RE = /^[a-z][a-z0-9_]{0,23}$/;
|
|
10
|
+
/** 前缀与工具名之间的分隔符。 */
|
|
11
|
+
export const KEY_SEPARATOR = "__";
|
|
12
|
+
/**
|
|
13
|
+
* slug 是否合法:除正则外,不得含连续下划线、不得以下划线结尾——否则 `a__b` + `c` 与 `a` + `b__c`
|
|
14
|
+
* 会拼出同一个 key。
|
|
15
|
+
*/
|
|
16
|
+
export function isValidSlug(slug) {
|
|
17
|
+
return APP_SLUG_RE.test(slug) && !slug.includes("__") && !slug.endsWith("_");
|
|
18
|
+
}
|
|
19
|
+
/** slug 不合法时的英文说明(给 validation_failed 用)。 */
|
|
20
|
+
export const SLUG_RULE = "Slug must start with a lowercase letter, contain only lowercase letters, digits and single underscores, not end with an underscore, and be at most 24 characters";
|
|
21
|
+
/**
|
|
22
|
+
* 由连接器名推导 slug:转小写,非 `[a-z0-9]` 的连续字符折成一个下划线,去掉首尾下划线与开头的数字 / 下划线,
|
|
23
|
+
* 截到 24 位(再去掉尾部下划线)。推导不出合法 slug(如名称全是中文)时返回 null,由调用方要求显式给出。
|
|
24
|
+
*/
|
|
25
|
+
export function deriveSlug(name) {
|
|
26
|
+
const s = name
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9]+/g, "_")
|
|
29
|
+
.replace(/^[^a-z]+/, "")
|
|
30
|
+
.slice(0, 24)
|
|
31
|
+
.replace(/_+$/, "");
|
|
32
|
+
return isValidSlug(s) ? s : null;
|
|
33
|
+
}
|
|
34
|
+
/** 拼 `<prefix>__<name>`。 */
|
|
35
|
+
export function toolKey(prefix, name) {
|
|
36
|
+
return `${prefix}${KEY_SEPARATOR}${name}`;
|
|
37
|
+
}
|
|
38
|
+
/** key 不合法时返回英文原因,合法时返回 null。 */
|
|
39
|
+
export function toolKeyIssue(key) {
|
|
40
|
+
if (key.length > TOOL_KEY_MAX) {
|
|
41
|
+
return `Tool key "${key}" is ${key.length} characters; the limit is ${TOOL_KEY_MAX}`;
|
|
42
|
+
}
|
|
43
|
+
if (!TOOL_KEY_RE.test(key)) {
|
|
44
|
+
return `Tool key "${key}" contains characters outside [a-zA-Z0-9_-]`;
|
|
45
|
+
}
|
|
46
|
+
return null;
|
|
47
|
+
}
|