@zackbart/connecta 0.28.1 → 0.29.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/CHANGELOG.md +788 -5
- package/README.md +62 -42
- package/bin/connecta.mjs +110 -139
- package/bin/meta-tool-names.d.mts +2 -0
- package/bin/meta-tool-names.mjs +9 -0
- package/bin/version.mjs +3 -0
- package/dist/access-tokens.js +53 -63
- package/dist/activity-request.js +8 -0
- package/dist/activity.d.ts +76 -42
- package/dist/activity.js +110 -42
- package/dist/auth/clerk-sdk/client.d.ts +65 -0
- package/dist/auth/clerk-sdk/client.js +5 -0
- package/dist/auth/clerk-sdk/generated.js +1845 -0
- package/dist/auth/clerk-transport.js +19 -0
- package/dist/auth/clerk.d.ts +17 -7
- package/dist/auth/clerk.js +189 -107
- package/dist/auth/cloudflare-access.js +25 -26
- package/dist/auth/downstream-client-metadata.d.ts +29 -0
- package/dist/auth/downstream-client-metadata.js +133 -0
- package/dist/auth/downstream-oauth.js +1584 -1580
- package/dist/auth/downstream-revocation.js +106 -0
- package/dist/auth/oauth-token-response.js +231 -0
- package/dist/auth/oauth-v2-migration.js +116 -0
- package/dist/auth/static-oauth.js +93 -71
- package/dist/auth-elicitation.js +283 -0
- package/dist/branding.d.ts +8 -16
- package/dist/branding.js +26 -59
- package/dist/byte-read-response.js +39 -0
- package/dist/call-admission.js +12 -16
- package/dist/catalog-cache.js +739 -0
- package/dist/catalog-drift.d.ts +50 -15
- package/dist/catalog-drift.js +365 -128
- package/dist/catalog-fingerprint.js +2 -4
- package/dist/catalog-freshness.js +13 -0
- package/dist/catalog-limits.js +2 -2
- package/dist/catalog-service.js +368 -224
- package/dist/catalog.js +43 -84
- package/dist/concurrency.js +3 -4
- package/dist/config-defaults.d.ts +39 -0
- package/dist/config-defaults.js +46 -0
- package/dist/config-schema.d.ts +181 -0
- package/dist/config-schema.js +435 -0
- package/dist/config-value-sources.js +102 -0
- package/dist/config.d.ts +631 -0
- package/dist/config.js +503 -0
- package/dist/connector-access.d.ts +1 -0
- package/dist/connector-access.js +13 -15
- package/dist/connector-caller.d.ts +8 -0
- package/dist/connector-caller.js +15 -6
- package/dist/connector-scope.js +1 -1
- package/dist/connectors/api-connector.d.ts +59 -7
- package/dist/connectors/api-connector.js +106 -19
- package/dist/connectors/api.js +4 -1
- package/dist/connectors/guarded-fetch.d.ts +144 -0
- package/dist/connectors/guarded-fetch.js +84 -35
- package/dist/connectors/negotiation-cache.js +46 -0
- package/dist/connectors/option-shapes.js +27 -0
- package/dist/connectors/remote-mcp.d.ts +30 -4
- package/dist/connectors/remote-mcp.js +1774 -320
- package/dist/connectors/resource-uri.js +335 -0
- package/dist/credential-contract.d.ts +10 -0
- package/dist/credential-rules.js +1 -3
- package/dist/credential-url.js +108 -0
- package/dist/credentials.d.ts +6 -1
- package/dist/credentials.js +27 -18
- package/dist/d1.d.ts +130 -0
- package/dist/d1.js +290 -0
- package/dist/describe-config.d.ts +165 -0
- package/dist/describe-config.js +315 -0
- package/dist/described.js +106 -0
- package/dist/downstream-input-context.js +119 -0
- package/dist/downstream-input.js +323 -0
- package/dist/errors.d.ts +97 -20
- package/dist/errors.js +158 -80
- package/dist/execute.js +453 -305
- package/dist/executor-admission.d.ts +1 -0
- package/dist/executor-admission.js +11 -15
- package/dist/executor-contract.d.ts +20 -0
- package/dist/executor-contract.js +48 -0
- package/dist/executor-result.js +24 -9
- package/dist/executors/quickjs-child.js +3 -4
- package/dist/executors/quickjs-runtime.js +147 -59
- package/dist/executors/quickjs.js +29 -35
- package/dist/favicon.js +1 -2
- package/dist/fix-prompt.js +1 -3
- package/dist/guest-runtime.js +188 -0
- package/dist/guest-types.d.ts +176 -0
- package/dist/guest-types.js +1 -0
- package/dist/html-security.js +24 -0
- package/dist/identity.js +1 -3
- package/dist/inbound-credential.js +52 -0
- package/dist/index.d.ts +24 -256
- package/dist/index.js +65 -478
- package/dist/invocation-auth.js +69 -0
- package/dist/invocation.js +230 -73
- package/dist/json-schema.d.ts +1 -1
- package/dist/mcp-client-context.js +35 -0
- package/dist/mcp-result.js +11 -7
- package/dist/meta-output.js +76 -0
- package/dist/meta-tool-names.d.ts +2 -0
- package/dist/meta-tool-names.js +3 -0
- package/dist/meta-tools.js +285 -209
- package/dist/module-contracts.d.ts +8 -23
- package/dist/node.d.ts +0 -2
- package/dist/node.js +2 -2
- package/dist/oauth-callback-outcome.js +1 -3
- package/dist/oauth-handoff.js +117 -0
- package/dist/oauth-sealing.js +20 -0
- package/dist/operator-record.d.ts +137 -0
- package/dist/operator-record.js +420 -0
- package/dist/operator-ui/assets.js +31 -0
- package/dist/operator-ui/contract.d.ts +72 -0
- package/dist/operator-ui/contract.js +1 -0
- package/dist/operator-ui/fix-prompts.d.ts +18 -0
- package/dist/operator-ui/generated.js +5 -4
- package/dist/operator-ui/model.d.ts +12 -87
- package/dist/operator-ui/model.js +2 -9
- package/dist/operator-ui/setup-commands.js +1 -3
- package/dist/operator-ui/view.d.ts +323 -0
- package/dist/operator-ui/view.js +62 -189
- package/dist/page-styles.js +2 -3
- package/dist/program-source.js +14 -2
- package/dist/{exempt-writes.js → program-writes.js} +55 -18
- package/dist/provider.d.ts +142 -0
- package/dist/provider.js +187 -0
- package/dist/providers/_shared/google/result-size.js +57 -0
- package/dist/providers/_shared/google/service-account.d.ts +58 -0
- package/dist/providers/_shared/google/service-account.js +500 -0
- package/dist/providers/_shared/google/workspace.d.ts +276 -0
- package/dist/providers/_shared/google/workspace.js +518 -0
- package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
- package/dist/providers/basecamp/index.js +997 -0
- package/dist/providers/basecamp/skill.generated.js +9 -0
- package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
- package/dist/providers/{breeze.js → breeze/index.js} +184 -140
- package/dist/providers/breeze/skill.generated.js +9 -0
- package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
- package/dist/providers/{ccb.js → ccb/index.js} +271 -116
- package/dist/providers/ccb/skill.generated.js +9 -0
- package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
- package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
- package/dist/providers/cloudflare/skill.generated.js +10 -0
- package/dist/providers/docs/index.d.ts +54 -0
- package/dist/providers/docs/index.js +1237 -0
- package/dist/providers/docs/skill.generated.js +9 -0
- package/dist/providers/drive/index.d.ts +53 -0
- package/dist/providers/drive/index.js +1523 -0
- package/dist/providers/drive/skill.generated.js +9 -0
- package/dist/providers/forms/index.d.ts +54 -0
- package/dist/providers/forms/index.js +1217 -0
- package/dist/providers/forms/skill.generated.js +11 -0
- package/dist/providers/github/auth.d.ts +32 -0
- package/dist/providers/github/auth.js +361 -0
- package/dist/providers/github/hosted.js +218 -0
- package/dist/providers/github/index.d.ts +13 -0
- package/dist/providers/github/index.js +140 -0
- package/dist/providers/github/key.js +100 -0
- package/dist/providers/github/rest.js +321 -0
- package/dist/providers/github/scope.d.ts +29 -0
- package/dist/providers/github/scope.js +124 -0
- package/dist/providers/github/skill.generated.js +8 -0
- package/dist/providers/gmail/index.d.ts +51 -0
- package/dist/providers/gmail/index.js +1436 -0
- package/dist/providers/gmail/skill.generated.js +9 -0
- package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
- package/dist/providers/linear/index.js +352 -0
- package/dist/providers/linear/skill.generated.js +8 -0
- package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
- package/dist/providers/mixpanel/index.js +416 -0
- package/dist/providers/mixpanel/skill.generated.js +9 -0
- package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
- package/dist/providers/{notion.js → notion/index.js} +226 -239
- package/dist/providers/notion/skill.generated.js +10 -0
- package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
- package/dist/providers/{overflow.js → overflow/index.js} +74 -111
- package/dist/providers/overflow/skill.generated.js +8 -0
- package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
- package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
- package/dist/providers/planning-center/skill.generated.js +10 -0
- package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
- package/dist/providers/revenuecat/index.js +557 -0
- package/dist/providers/revenuecat/skill.generated.js +11 -0
- package/dist/providers/sheets/index.d.ts +54 -0
- package/dist/providers/sheets/index.js +1237 -0
- package/dist/providers/sheets/skill.generated.js +10 -0
- package/dist/providers/slides/index.d.ts +53 -0
- package/dist/providers/slides/index.js +2645 -0
- package/dist/providers/slides/skill.generated.js +9 -0
- package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
- package/dist/providers/stripe/index.js +266 -0
- package/dist/providers/stripe/skill.generated.js +11 -0
- package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
- package/dist/providers/{tithely.js → tithely/index.js} +60 -91
- package/dist/providers/tithely/skill.generated.js +8 -0
- package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
- package/dist/providers/vercel/index.js +1038 -0
- package/dist/providers/vercel/mcp-ownership.js +212 -0
- package/dist/providers/vercel/skill.generated.js +11 -0
- package/dist/registry.d.ts +108 -171
- package/dist/registry.js +513 -925
- package/dist/request-state.js +21 -0
- package/dist/resource-read.js +100 -0
- package/dist/result-shapes.js +17 -49
- package/dist/retired-toolkits.js +1 -1
- package/dist/routes/access-tokens.js +3 -6
- package/dist/routes/activity-context.js +21 -0
- package/dist/routes/activity-disclosure.js +40 -0
- package/dist/routes/activity.js +59 -21
- package/dist/routes/actor-labels.js +3 -50
- package/dist/routes/connect.js +221 -0
- package/dist/routes/credentials.js +15 -27
- package/dist/routes/mcp.js +356 -130
- package/dist/routes/oauth-client-metadata.js +15 -0
- package/dist/routes/oauth-management.js +45 -107
- package/dist/routes/oauth.js +110 -57
- package/dist/routes/operator.js +3 -3
- package/dist/routes/shared.d.ts +25 -64
- package/dist/routes/shared.js +160 -80
- package/dist/routes/skills.js +30 -0
- package/dist/routes/ui-config.js +225 -0
- package/dist/routes/ui-data.js +40 -35
- package/dist/routes/ui.js +66 -56
- package/dist/runtime/admission.js +4 -2
- package/dist/runtime/call-admission.js +3 -1
- package/dist/runtime/connector-scope.js +1 -4
- package/dist/runtime/run.js +10 -39
- package/dist/runtime/services.js +12 -117
- package/dist/runtime/shared-read.js +1 -3
- package/dist/runtime/storage.js +8 -1
- package/dist/sent-secrets.d.ts +52 -0
- package/dist/sent-secrets.js +474 -0
- package/dist/server.js +28 -71
- package/dist/skills.js +406 -174
- package/dist/sqlite.d.ts +48 -0
- package/dist/sqlite.js +166 -0
- package/dist/storage/keys.js +428 -0
- package/dist/storage/memory.js +7 -0
- package/dist/storage/sql.d.ts +66 -0
- package/dist/storage/sql.js +534 -0
- package/dist/timeout.js +4 -2
- package/dist/tool-name.js +17 -0
- package/dist/tool-safety.d.ts +9 -35
- package/dist/tool-safety.js +20 -40
- package/dist/types.d.ts +320 -54
- package/dist/types.js +0 -1
- package/dist/ui.d.ts +7 -19
- package/dist/ui.js +76 -90
- package/dist/url-safety.js +3 -6
- package/dist/usage-guide.js +137 -0
- package/dist/validate.d.ts +7 -0
- package/dist/validate.js +309 -47
- package/dist/version.d.ts +1 -7
- package/dist/version.js +3 -7
- package/dist/worker.d.ts +11 -0
- package/dist/worker.js +434 -0
- package/documentation/architecture.md +664 -231
- package/documentation/auth.md +936 -546
- package/documentation/code-mode.md +501 -312
- package/documentation/meta-tools.md +449 -200
- package/documentation/operator-tests.md +93 -0
- package/documentation/provider-migration-0.29.md +60 -0
- package/examples/worker/AGENTS.md +34 -12
- package/examples/worker/README.md +286 -255
- package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
- package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
- package/examples/worker/src/connecta.config.ts +151 -0
- package/examples/worker/src/index.ts +14 -197
- package/examples/worker/wrangler.jsonc +15 -35
- package/package.json +120 -54
- package/templates/node/.dockerignore +1 -2
- package/templates/node/.env.example +20 -21
- package/templates/node/AGENTS.md +21 -17
- package/templates/node/Dockerfile +3 -5
- package/templates/node/README.md +133 -58
- package/templates/node/docker-compose.yml +11 -12
- package/templates/node/package.json +4 -2
- package/templates/node/src/connecta.config.ts +119 -0
- package/templates/node/src/index.ts +9 -154
- package/templates/node/src/provision-token.ts +17 -0
- package/AGENTS.md +0 -170
- package/dist/artifacts/connector.d.ts +0 -58
- package/dist/artifacts/connector.js +0 -730
- package/dist/artifacts/document.js +0 -86
- package/dist/artifacts/guide.js +0 -140
- package/dist/artifacts/html-scan.js +0 -329
- package/dist/artifacts/json.js +0 -78
- package/dist/artifacts/kv-store.d.ts +0 -20
- package/dist/artifacts/kv-store.js +0 -140
- package/dist/artifacts/markdown.js +0 -478
- package/dist/artifacts/module.d.ts +0 -37
- package/dist/artifacts/module.js +0 -66
- package/dist/artifacts/operations.d.ts +0 -197
- package/dist/artifacts/operations.js +0 -1002
- package/dist/artifacts/refresh.d.ts +0 -55
- package/dist/artifacts/refresh.js +0 -236
- package/dist/artifacts/routes.js +0 -206
- package/dist/artifacts/types.d.ts +0 -214
- package/dist/artifacts/types.js +0 -22
- package/dist/artifacts/validate.d.ts +0 -62
- package/dist/artifacts/validate.js +0 -651
- package/dist/artifacts.d.ts +0 -6
- package/dist/artifacts.js +0 -9
- package/dist/auth/bearer.d.ts +0 -11
- package/dist/auth/bearer.js +0 -50
- package/dist/providers/basecamp.js +0 -445
- package/dist/providers/linear.js +0 -217
- package/dist/providers/mixpanel.js +0 -247
- package/dist/providers/revenuecat.js +0 -317
- package/dist/providers/stripe.js +0 -253
- package/dist/providers/vercel.js +0 -1253
- package/dist/storage/file.d.ts +0 -15
- package/dist/storage/file.js +0 -455
- package/ethos.md +0 -93
- package/examples/worker/src/cloudflare-kv.ts +0 -43
- package/examples/worker/src/d1-activity-row.ts +0 -155
- package/examples/worker/src/d1-activity.ts +0 -147
- package/examples/worker/src/d1-storage.ts +0 -138
- package/examples/worker/src/r2-artifact-blobs.ts +0 -29
- package/templates/node/src/file-activity.ts +0 -182
package/dist/index.js
CHANGED
|
@@ -1,232 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { describeConfigSources } from "./config-value-sources.js";
|
|
2
|
+
import { credentialTestRule, describeCredentialTestMismatch } from "./credential-rules.js";
|
|
2
3
|
import { Registry } from "./registry.js";
|
|
3
|
-
import {
|
|
4
|
+
import { parseConnectorAccess, POOL_NAME_RE } from "./connector-access.js";
|
|
4
5
|
import { createFetchHandler } from "./server.js";
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { AdmissionController, executorName, isAdmittingExecutor, withExecutorAdmission
|
|
10
|
-
|
|
11
|
-
import { disposeEdgeRuntime } from "./runtime/run.js";
|
|
12
|
-
import { NO_EXEMPTIONS } from "./tool-safety.js";
|
|
13
|
-
import { createCoreRuntime, resolveLogger } from "./runtime/services.js";
|
|
14
|
-
const REQUEST_ADMISSION_DEFAULTS = {
|
|
15
|
-
concurrency: 16,
|
|
16
|
-
maxQueueSize: 32,
|
|
17
|
-
queueTimeoutMs: 5_000,
|
|
18
|
-
retryAfterMs: 1_000,
|
|
19
|
-
};
|
|
20
|
-
const DEFAULT_REQUEST_MAX_DURATION_MS = 300_000;
|
|
21
|
-
const CODE_ADMISSION_DEFAULTS = {
|
|
22
|
-
concurrency: 2,
|
|
23
|
-
maxQueueSize: 8,
|
|
24
|
-
queueTimeoutMs: 5_000,
|
|
25
|
-
retryAfterMs: 1_000,
|
|
26
|
-
};
|
|
27
|
-
function admissionController(options, defaults, maxDurationMs) {
|
|
28
|
-
return new AdmissionController({
|
|
29
|
-
concurrency: options?.concurrency ?? defaults.concurrency,
|
|
30
|
-
maxQueueSize: options?.maxQueueSize ?? defaults.maxQueueSize,
|
|
31
|
-
queueTimeoutMs: options?.queueTimeoutMs ?? defaults.queueTimeoutMs,
|
|
32
|
-
retryAfterMs: options?.retryAfterMs ?? defaults.retryAfterMs,
|
|
33
|
-
...(maxDurationMs !== undefined ? { maxDurationMs } : {}),
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
/** Bearer providers are checked before Clerk (per spec). */
|
|
37
|
-
function normalizeAuth(auth) {
|
|
38
|
-
const list = auth ? (Array.isArray(auth) ? auth : [auth]) : [];
|
|
39
|
-
return [...list].sort((a, b) => {
|
|
40
|
-
const rank = (x) => (x.kind === "bearer" ? 0 : 1);
|
|
41
|
-
return rank(a) - rank(b);
|
|
42
|
-
});
|
|
43
|
-
}
|
|
44
|
-
const admissionPoolSchema = {
|
|
45
|
-
concurrency: null,
|
|
46
|
-
maxQueueSize: null,
|
|
47
|
-
queueTimeoutMs: null,
|
|
48
|
-
retryAfterMs: null,
|
|
49
|
-
};
|
|
50
|
-
const requestAdmissionSchema = {
|
|
51
|
-
...admissionPoolSchema,
|
|
52
|
-
maxDurationMs: null,
|
|
53
|
-
};
|
|
54
|
-
const CONFIG_SCHEMA = {
|
|
55
|
-
connectors: null,
|
|
56
|
-
auth: null,
|
|
57
|
-
identity: {
|
|
58
|
-
connectorAccess: null,
|
|
59
|
-
activityAccess: null,
|
|
60
|
-
credentialAdministration: null,
|
|
61
|
-
personalConnection: null,
|
|
62
|
-
accessTokenManagement: null,
|
|
63
|
-
},
|
|
64
|
-
pools: null,
|
|
65
|
-
storage: null,
|
|
66
|
-
publicUrl: null,
|
|
67
|
-
allowedOrigins: null,
|
|
68
|
-
activity: null,
|
|
69
|
-
vault: null,
|
|
70
|
-
ui: null,
|
|
71
|
-
artifacts: null,
|
|
72
|
-
accessTokens: null,
|
|
73
|
-
artifactOrigin: null,
|
|
74
|
-
discovery: {
|
|
75
|
-
concurrency: null,
|
|
76
|
-
catalogTtlSeconds: null,
|
|
77
|
-
persistCatalog: null,
|
|
78
|
-
staleCatalogSeconds: null,
|
|
79
|
-
probeTimeoutMs: null,
|
|
80
|
-
},
|
|
81
|
-
results: {
|
|
82
|
-
maxStashBytes: null,
|
|
83
|
-
maxStashEntries: null,
|
|
84
|
-
},
|
|
85
|
-
calls: {
|
|
86
|
-
defaultTimeoutMs: null,
|
|
87
|
-
maxResultBytes: null,
|
|
88
|
-
},
|
|
89
|
-
execute: {
|
|
90
|
-
maxEmittedBytes: null,
|
|
91
|
-
maxEmittedBlocks: null,
|
|
92
|
-
maxHostCalls: null,
|
|
93
|
-
hostCallTimeoutMs: null,
|
|
94
|
-
watchdogMs: null,
|
|
95
|
-
maxWrites: null,
|
|
96
|
-
approval: null,
|
|
97
|
-
},
|
|
98
|
-
admission: {
|
|
99
|
-
requests: requestAdmissionSchema,
|
|
100
|
-
code: admissionPoolSchema,
|
|
101
|
-
},
|
|
102
|
-
logger: null,
|
|
103
|
-
serverInfo: {
|
|
104
|
-
name: null,
|
|
105
|
-
version: null,
|
|
106
|
-
title: null,
|
|
107
|
-
websiteUrl: null,
|
|
108
|
-
icons: [
|
|
109
|
-
{
|
|
110
|
-
src: null,
|
|
111
|
-
mimeType: null,
|
|
112
|
-
sizes: null,
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
},
|
|
116
|
-
deploymentInfo: null,
|
|
117
|
-
executor: null,
|
|
118
|
-
};
|
|
119
|
-
function unknownOptionPaths(value, path, schema) {
|
|
120
|
-
if (schema === null)
|
|
121
|
-
return [];
|
|
122
|
-
if (Array.isArray(schema)) {
|
|
123
|
-
if (!Array.isArray(value))
|
|
124
|
-
return [];
|
|
125
|
-
return value.flatMap((entry, index) => unknownOptionPaths(entry, `${path}[${index}]`, schema[0]));
|
|
126
|
-
}
|
|
127
|
-
if (typeof value !== "object" || value === null)
|
|
128
|
-
return [];
|
|
129
|
-
const known = new Set(Object.keys(schema));
|
|
130
|
-
const unknown = Reflect.ownKeys(value)
|
|
131
|
-
.filter((key) => typeof key !== "string" || !known.has(key))
|
|
132
|
-
.map((key) => `${path}.${String(key)}`)
|
|
133
|
-
.sort();
|
|
134
|
-
if (unknown.length > 0)
|
|
135
|
-
return unknown;
|
|
136
|
-
for (const [key, childSchema] of Object.entries(schema)) {
|
|
137
|
-
unknown.push(...unknownOptionPaths(value[key], `${path}.${key}`, childSchema));
|
|
138
|
-
}
|
|
139
|
-
return unknown;
|
|
140
|
-
}
|
|
141
|
-
/** Pause-only options #672 removed with `resume_execution`. */
|
|
142
|
-
const RETIRED_PAUSE_OPTIONS = [
|
|
143
|
-
"ConnectaConfig.execute.resumableWrites",
|
|
144
|
-
"ConnectaConfig.execute.pausedRunTtlSeconds",
|
|
145
|
-
];
|
|
146
|
-
function rejectUnknownOptions(paths) {
|
|
147
|
-
if (paths.length === 0)
|
|
148
|
-
return;
|
|
149
|
-
throw new Error(`Unknown Connecta configuration option${paths.length === 1 ? "" : "s"}:\n` +
|
|
150
|
-
paths.map((path) => `- ${path}`).join("\n") +
|
|
151
|
-
(paths.includes("ConnectaConfig.credentials") ? "\nUse vault: encryptedCredentialVault(storage, key) from @zackbart/connecta/credentials." : "") +
|
|
152
|
-
(paths.includes("ConnectaConfig.branding") ? "\nMove branding into ui: operatorUi({ branding }) from @zackbart/connecta/ui." : "") +
|
|
153
|
-
(paths.some((path) => RETIRED_PAUSE_OPTIONS.includes(path))
|
|
154
|
-
? "\nPrograms no longer pause at writes, so there is nothing to configure: execute_code runs read-only and config-exempt tools, and every other write goes through call_destructive_tool (issue #672). Delete the option."
|
|
155
|
-
: ""));
|
|
156
|
-
}
|
|
157
|
-
/** Reject JavaScript typos and removed options before construction does work. */
|
|
158
|
-
function assertKnownConfig(config) {
|
|
159
|
-
rejectUnknownOptions(unknownOptionPaths(config, "ConnectaConfig", CONFIG_SCHEMA));
|
|
160
|
-
if (config.results !== undefined) {
|
|
161
|
-
if (!config.results || typeof config.results !== "object" || Array.isArray(config.results)) {
|
|
162
|
-
throw new Error("ConnectaConfig.results must be an object");
|
|
163
|
-
}
|
|
164
|
-
for (const key of ["maxStashBytes", "maxStashEntries"]) {
|
|
165
|
-
const value = config.results[key];
|
|
166
|
-
if (value !== undefined && (!Number.isSafeInteger(value) || value < 0)) {
|
|
167
|
-
throw new Error(`ConnectaConfig.results.${key} must be a non-negative safe integer`);
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
if (config.vault && (["get", "getAll", "set", "setAll", "metadata", "delete"].some(key => typeof config.vault[key] !== "function") || ["seal", "open"].some(key => !["undefined", "function"].includes(typeof config.vault[key]))))
|
|
172
|
-
throw new Error("ConnectaConfig.vault must implement CredentialVault");
|
|
173
|
-
if (config.ui && (typeof config.ui.handle !== "function" || typeof config.ui.credentialHandoffUrl !== "function" || !Array.isArray(config.ui.reservedPaths)))
|
|
174
|
-
throw new Error("ConnectaConfig.ui must be created with operatorUi(...)");
|
|
175
|
-
const activity = config.activity;
|
|
176
|
-
if (activity !== undefined &&
|
|
177
|
-
(typeof activity !== "object" ||
|
|
178
|
-
activity === null ||
|
|
179
|
-
typeof activity.recordTool !== "function")) {
|
|
180
|
-
throw new Error("ConnectaConfig.activity must be created with activityHistory(...)");
|
|
181
|
-
}
|
|
182
|
-
if (config.accessTokens !== undefined && (!config.accessTokens ||
|
|
183
|
-
typeof config.accessTokens.auth?.authorize !== "function" ||
|
|
184
|
-
config.accessTokens.auth.interactiveOperator ||
|
|
185
|
-
typeof config.accessTokens.handle !== "function")) {
|
|
186
|
-
throw new Error("ConnectaConfig.accessTokens must be created with accessTokens(storage) from @zackbart/connecta/auth/access-tokens; reuse your existing storage to preserve tokens");
|
|
187
|
-
}
|
|
188
|
-
const artifacts = config.artifacts;
|
|
189
|
-
if (artifacts !== undefined) {
|
|
190
|
-
const connector = artifacts?.connector;
|
|
191
|
-
if (typeof artifacts !== "object" ||
|
|
192
|
-
artifacts === null ||
|
|
193
|
-
!connector ||
|
|
194
|
-
connector.id !== "artifacts" ||
|
|
195
|
-
typeof connector.callTool !== "function" ||
|
|
196
|
-
typeof artifacts.handle !== "function") {
|
|
197
|
-
throw new Error("ConnectaConfig.artifacts must be created with artifacts(...) from @zackbart/connecta/artifacts");
|
|
198
|
-
}
|
|
199
|
-
if (config.connectors?.some((candidate) => candidate?.id === "artifacts")) {
|
|
200
|
-
throw new Error('Connector id "artifacts" is reserved by the artifacts module; rename ' +
|
|
201
|
-
"your connector or drop the artifacts option");
|
|
202
|
-
}
|
|
203
|
-
if (!config.publicUrl) {
|
|
204
|
-
throw new Error("ConnectaConfig.artifacts needs publicUrl: artifact links are shared " +
|
|
205
|
-
"with teammates, so they must name the deployment's own origin, never " +
|
|
206
|
-
"one taken from a request's Host header");
|
|
207
|
-
}
|
|
208
|
-
}
|
|
209
|
-
if (config.artifactOrigin !== undefined) {
|
|
210
|
-
if (!config.artifacts || !config.ui || !config.publicUrl) {
|
|
211
|
-
throw new Error("ConnectaConfig.artifactOrigin needs artifacts, ui, and publicUrl");
|
|
212
|
-
}
|
|
213
|
-
if (typeof config.artifactOrigin !== "string") {
|
|
214
|
-
throw new Error("ConnectaConfig.artifactOrigin must be an HTTPS origin");
|
|
215
|
-
}
|
|
216
|
-
let origin;
|
|
217
|
-
try {
|
|
218
|
-
origin = new URL(config.artifactOrigin);
|
|
219
|
-
}
|
|
220
|
-
catch {
|
|
221
|
-
throw new Error("ConnectaConfig.artifactOrigin must be an HTTPS origin");
|
|
222
|
-
}
|
|
223
|
-
if (origin.protocol !== "https:" ||
|
|
224
|
-
origin.toString() !== `${origin.origin}/` ||
|
|
225
|
-
origin.origin === new URL(config.publicUrl).origin) {
|
|
226
|
-
throw new Error("ConnectaConfig.artifactOrigin must be a distinct HTTPS origin");
|
|
227
|
-
}
|
|
228
|
-
}
|
|
229
|
-
}
|
|
6
|
+
import { droppedBrandingUrls, droppedThemeTokens, droppedUiAuthUrls } from "./branding.js";
|
|
7
|
+
import { readConfig } from "./config.js";
|
|
8
|
+
import { describeConfig } from "./describe-config.js";
|
|
9
|
+
export { customExecutor } from "./executor-contract.js";
|
|
10
|
+
import { AdmissionController, executorName, isAdmittingExecutor, withExecutorAdmission } from "./executor-admission.js";
|
|
11
|
+
export { defineConfig } from "./config.js";
|
|
230
12
|
/**
|
|
231
13
|
* Validate declared pools against the connector set. Everything checkable at
|
|
232
14
|
* construction throws here: a malformed name, an unparseable grant, an
|
|
@@ -238,27 +20,13 @@ function resolvePools(pools, registry) {
|
|
|
238
20
|
const resolved = new Map();
|
|
239
21
|
if (!pools)
|
|
240
22
|
return resolved;
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
23
|
+
// The schema has already refused a pool that is not an object, a missing or
|
|
24
|
+
// non-array `tools`, a non-function `grant`, and a misspelled key — a
|
|
25
|
+
// misspelled `grant` would otherwise boot as a deny-all pool.
|
|
244
26
|
for (const [name, pool] of Object.entries(pools)) {
|
|
245
27
|
if (!POOL_NAME_RE.test(name)) {
|
|
246
28
|
throw new Error(`ConnectaConfig.pools: pool name "${name}" must match [a-z0-9_-]+`);
|
|
247
29
|
}
|
|
248
|
-
if (!pool || typeof pool !== "object" || !Array.isArray(pool.tools)) {
|
|
249
|
-
throw new Error(`ConnectaConfig.pools.${name}: tools must be an array of connector ids or connector.tool addresses`);
|
|
250
|
-
}
|
|
251
|
-
if (pool.grant !== undefined && typeof pool.grant !== "function") {
|
|
252
|
-
throw new Error(`ConnectaConfig.pools.${name}: grant must be a function`);
|
|
253
|
-
}
|
|
254
|
-
// A misspelled `grant` would otherwise boot as a deny-all pool with only a
|
|
255
|
-
// per-request log line to say so; that is fail-closed, but the rule here
|
|
256
|
-
// is that structural mistakes refuse to boot.
|
|
257
|
-
for (const key of Object.keys(pool)) {
|
|
258
|
-
if (key !== "tools" && key !== "grant") {
|
|
259
|
-
throw new Error(`ConnectaConfig.pools.${name}: unknown option "${key}"`);
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
30
|
let access;
|
|
263
31
|
try {
|
|
264
32
|
access = parseConnectorAccess(pool.tools);
|
|
@@ -284,92 +52,24 @@ function resolvePools(pools, registry) {
|
|
|
284
52
|
}
|
|
285
53
|
}
|
|
286
54
|
}
|
|
287
|
-
resolved.set(name, { access, grant: pool.grant ?? (() => false) });
|
|
55
|
+
resolved.set(name, { access, trust: pool.trust, grant: pool.grant ?? (() => false) });
|
|
288
56
|
}
|
|
289
57
|
return resolved;
|
|
290
58
|
}
|
|
291
|
-
/**
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
* tools do not include all throw. Remote catalogs load lazily, so an address
|
|
295
|
-
* on one is kept and simply never matches a tool it does not serve.
|
|
296
|
-
*/
|
|
297
|
-
function resolveApprovalPolicy(approval, registry) {
|
|
298
|
-
for (const connector of registry.listConnectors()) {
|
|
299
|
-
if (connector.approval !== undefined && connector.approval !== "never") {
|
|
300
|
-
throw new Error(`Connector "${connector.id}": approval must be "never" or omitted`);
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
if (approval === undefined)
|
|
304
|
-
return NO_EXEMPTIONS;
|
|
305
|
-
if (!approval || typeof approval !== "object" || Array.isArray(approval)) {
|
|
306
|
-
throw new Error("ConnectaConfig.execute.approval must be an object keyed by connector ids and connector.tool addresses");
|
|
307
|
-
}
|
|
308
|
-
const connectors = new Map();
|
|
309
|
-
const tools = new Map();
|
|
310
|
-
for (const [key, value] of Object.entries(approval)) {
|
|
311
|
-
const where = `ConnectaConfig.execute.approval[${JSON.stringify(key)}]`;
|
|
312
|
-
if (value !== "never" && value !== "ask") {
|
|
313
|
-
throw new Error(`${where} must be "never" or "ask"`);
|
|
314
|
-
}
|
|
315
|
-
const dot = key.indexOf(".");
|
|
316
|
-
const id = dot === -1 ? key : key.slice(0, dot);
|
|
317
|
-
const tool = dot === -1 ? undefined : key.slice(dot + 1);
|
|
318
|
-
if (!id || tool === "") {
|
|
319
|
-
throw new Error(`${where}: keys are connector ids or connector.tool addresses`);
|
|
320
|
-
}
|
|
321
|
-
const connector = registry.getConnector(id);
|
|
322
|
-
if (!connector)
|
|
323
|
-
throw new Error(`${where}: unknown connector "${id}"`);
|
|
324
|
-
if (tool === undefined) {
|
|
325
|
-
connectors.set(id, value);
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
if (connector.staticTools &&
|
|
329
|
-
!connector.staticTools.some((candidate) => candidate.name === tool)) {
|
|
330
|
-
throw new Error(`${where}: connector "${id}" has no tool "${tool}"`);
|
|
331
|
-
}
|
|
332
|
-
tools.set(key, value);
|
|
333
|
-
}
|
|
334
|
-
return { connectors, tools };
|
|
335
|
-
}
|
|
336
|
-
/** A positive whole number, or the default when the value is unusable. */
|
|
337
|
-
function positiveWhole(value, fallback) {
|
|
338
|
-
return typeof value === "number" && Number.isFinite(value) && value >= 1
|
|
339
|
-
? Math.trunc(value)
|
|
340
|
-
: fallback;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* One-time construction warnings for deployment shapes that run fine but are
|
|
344
|
-
* usually unintended. Warning-only — never throws and never changes behavior;
|
|
345
|
-
* each deployment-wide condition emits at most one `logger.warn`, and each
|
|
346
|
-
* per-connector condition at most one per connector it names.
|
|
347
|
-
*/
|
|
348
|
-
function warnInsecureConfig(config, inboundAuth, logger) {
|
|
59
|
+
/** Construction warnings for valid but usually unintended deployment choices. */
|
|
60
|
+
function warnInsecureConfig(config) {
|
|
61
|
+
const { auth: inboundAuth, logger } = config;
|
|
349
62
|
const oauthConnectors = config.connectors.filter((c) => c.finishAuth);
|
|
350
63
|
const hasCredentialConnector = config.connectors.some((c) => c.credential);
|
|
351
64
|
// Static API headers can carry secrets without declaring credential hooks.
|
|
352
65
|
// Any configured connector warrants the open-deployment warning.
|
|
353
|
-
if (inboundAuth.length === 0 &&
|
|
354
|
-
(config.connectors.length > 0 || config.artifacts)) {
|
|
66
|
+
if (inboundAuth.length === 0 && config.connectors.length > 0) {
|
|
355
67
|
logger.warn("[connecta] running with no inbound authentication: any caller can " +
|
|
356
68
|
"invoke every shared connector. " +
|
|
357
69
|
(hasCredentialConnector || oauthConnectors.length > 0
|
|
358
70
|
? "Configured credentials and downstream OAuth grants are exposed to those calls. "
|
|
359
71
|
: "") +
|
|
360
|
-
"Configure
|
|
361
|
-
}
|
|
362
|
-
// Artifact pages mount inside the operator UI and open only for an
|
|
363
|
-
// authenticated viewer; either missing leaves the connector with no page.
|
|
364
|
-
if (config.artifacts && !config.ui) {
|
|
365
|
-
logger.warn("[connecta] artifacts is configured without ui: agents can publish and " +
|
|
366
|
-
"read artifacts, but there is no viewer, so their links answer 404. " +
|
|
367
|
-
"Add ui: operatorUi() to serve artifact pages.");
|
|
368
|
-
}
|
|
369
|
-
else if (config.artifacts && inboundAuth.length === 0) {
|
|
370
|
-
logger.warn("[connecta] artifacts is configured with no inbound authentication: " +
|
|
371
|
-
"artifact pages refuse every request, because there is no team to " +
|
|
372
|
-
"show them to. Configure `auth` to open them.");
|
|
72
|
+
"Configure Clerk, Cloudflare Access on Workers, or accessTokens(storage) to gate access.");
|
|
373
73
|
}
|
|
374
74
|
// Unset publicUrl with OAuth connectors: the downstream redirect_uri is
|
|
375
75
|
// derived per-request from the attacker-influenced inbound Host header.
|
|
@@ -463,177 +163,68 @@ function warnInsecureConfig(config, inboundAuth, logger) {
|
|
|
463
163
|
}
|
|
464
164
|
}
|
|
465
165
|
export function createConnecta(config) {
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
}
|
|
473
|
-
const storage = config.storage ?? memoryStorage();
|
|
474
|
-
const logger = resolveLogger(config.logger);
|
|
475
|
-
const credentialVault = config.vault;
|
|
476
|
-
const configuredAuth = normalizeAuth([
|
|
477
|
-
...(config.accessTokens ? [config.accessTokens.auth] : []),
|
|
478
|
-
...normalizeAuth(config.auth),
|
|
479
|
-
]);
|
|
480
|
-
const serverInfo = {
|
|
481
|
-
...config.serverInfo,
|
|
482
|
-
name: config.serverInfo?.name ?? "connecta",
|
|
483
|
-
version: config.serverInfo?.version ?? CONNECTA_VERSION,
|
|
484
|
-
};
|
|
485
|
-
// The artifacts module contributes one prebuilt connector, appended like any
|
|
486
|
-
// configured one: same catalog, invocation, admission, and activity.
|
|
487
|
-
const connectors = config.artifacts
|
|
488
|
-
? [...config.connectors, config.artifacts.connector]
|
|
489
|
-
: config.connectors;
|
|
490
|
-
const registry = new Registry(connectors, {
|
|
166
|
+
// Every structural check runs here, before any work: what comes back is the
|
|
167
|
+
// configuration the deployment runs with, defaults applied once.
|
|
168
|
+
const { input, resolved } = readConfig(config);
|
|
169
|
+
const { logger } = resolved;
|
|
170
|
+
const storage = resolved.storage;
|
|
171
|
+
const registry = new Registry([...resolved.connectors], {
|
|
491
172
|
storage,
|
|
492
173
|
logger,
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
174
|
+
publicUrl: resolved.publicUrl,
|
|
175
|
+
oauthClientName: resolved.serverInfo.name,
|
|
176
|
+
credentialVault: resolved.vault,
|
|
177
|
+
credentialUi: Boolean(resolved.ui),
|
|
178
|
+
catalogDriftActivity: resolved.activity?.store
|
|
496
179
|
? {
|
|
497
|
-
sink:
|
|
498
|
-
|
|
499
|
-
serverInfo,
|
|
500
|
-
...(
|
|
501
|
-
? { deploymentId: config.activity.deploymentId }
|
|
502
|
-
: {}),
|
|
180
|
+
sink: resolved.activity.store,
|
|
181
|
+
recordChange: resolved.activity.recordChange,
|
|
182
|
+
serverInfo: resolved.serverInfo,
|
|
183
|
+
...(resolved.activity.deploymentId !== undefined ? { deploymentId: resolved.activity.deploymentId } : {}),
|
|
503
184
|
}
|
|
504
185
|
: undefined,
|
|
505
|
-
toolCacheTtlSeconds:
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
maxResultBytes:
|
|
509
|
-
results:
|
|
186
|
+
toolCacheTtlSeconds: resolved.discovery.catalogTtlSeconds,
|
|
187
|
+
catalogMinTtlSeconds: resolved.discovery.catalogMinTtlSeconds,
|
|
188
|
+
catalogMaxTtlSeconds: resolved.discovery.catalogMaxTtlSeconds,
|
|
189
|
+
maxResultBytes: resolved.calls.maxResultBytes,
|
|
190
|
+
results: resolved.results,
|
|
191
|
+
classification: resolved.classification,
|
|
510
192
|
});
|
|
511
|
-
const
|
|
512
|
-
|
|
513
|
-
const
|
|
514
|
-
const maxWrites = positiveWhole(config.execute?.maxWrites, DEFAULT_MAX_WRITES);
|
|
515
|
-
warnInsecureConfig(config, inboundAuth, logger);
|
|
516
|
-
const requestAdmission = admissionController(config.admission?.requests, REQUEST_ADMISSION_DEFAULTS, config.admission?.requests?.maxDurationMs ?? DEFAULT_REQUEST_MAX_DURATION_MS);
|
|
517
|
-
const configuredCodeAdmission = admissionController(config.admission?.code, CODE_ADMISSION_DEFAULTS);
|
|
193
|
+
const pools = resolvePools(resolved.pools, registry);
|
|
194
|
+
warnInsecureConfig(resolved);
|
|
195
|
+
const requestAdmission = new AdmissionController(resolved.admission.requests);
|
|
518
196
|
let codeAdmission;
|
|
519
|
-
let executor =
|
|
197
|
+
let executor = resolved.executor;
|
|
520
198
|
// Read the identity off the configured executor, before any wrapper hides
|
|
521
199
|
// it behind an anonymous object literal.
|
|
522
200
|
const configuredExecutorName = executorName(executor);
|
|
523
|
-
|
|
524
|
-
|
|
201
|
+
const executorAdmits = isAdmittingExecutor(executor);
|
|
202
|
+
if (!executorAdmits) {
|
|
203
|
+
codeAdmission = new AdmissionController(resolved.admission.code);
|
|
525
204
|
executor = withExecutorAdmission(executor, codeAdmission);
|
|
526
205
|
}
|
|
527
|
-
else if (
|
|
206
|
+
else if (input.admission?.code) {
|
|
528
207
|
logger.warn("[connecta] admission.code is ignored because the configured executor " +
|
|
529
208
|
"implements acquire() and owns its admission pool; configure that " +
|
|
530
209
|
"executor's concurrency and queue options instead.");
|
|
531
210
|
}
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
maxEmittedBytes: config.execute?.maxEmittedBytes,
|
|
540
|
-
maxEmittedBlocks: config.execute?.maxEmittedBlocks,
|
|
541
|
-
maxHostCalls: config.execute?.maxHostCalls,
|
|
542
|
-
hostCallTimeoutMs: config.execute?.hostCallTimeoutMs,
|
|
543
|
-
watchdogMs: config.execute?.watchdogMs,
|
|
544
|
-
failOnInvocationFailure: true,
|
|
545
|
-
// A connector's own `approval: "never"` still applies when policy maps
|
|
546
|
-
// are empty. Override every shared connector explicitly for refresh.
|
|
547
|
-
approval: {
|
|
548
|
-
connectors: new Map(sharedIds.map((id) => [id, "ask"])),
|
|
549
|
-
tools: new Map(),
|
|
550
|
-
},
|
|
551
|
-
};
|
|
552
|
-
config.artifacts.bindRefresh({
|
|
553
|
-
...(config.ui?.branding ? { branding: config.ui.branding } : {}),
|
|
554
|
-
claimMs: runClaimMs(refreshConfig),
|
|
555
|
-
execute: async (program, owner, signal) => {
|
|
556
|
-
if (!owner)
|
|
557
|
-
throw new Error("Refresh owner is missing; reconfigure this program.");
|
|
558
|
-
let access = parseConnectorAccess(config.identity?.connectorAccess
|
|
559
|
-
? await config.identity.connectorAccess(owner.identity) : "all", { allowReadOnly: true });
|
|
560
|
-
if (owner.pool) {
|
|
561
|
-
const pool = pools.get(owner.pool);
|
|
562
|
-
if (!pool || await pool.grant(owner.identity) !== true) {
|
|
563
|
-
throw new Error("Refresh owner's pool grant is no longer available.");
|
|
564
|
-
}
|
|
565
|
-
access = intersectAccess(access, pool.access);
|
|
566
|
-
}
|
|
567
|
-
if (access.connectorIds !== "all" && !access.connectorIds.includes("artifacts")) {
|
|
568
|
-
throw new Error("Refresh owner no longer has artifact publishing access.");
|
|
569
|
-
}
|
|
570
|
-
if (access.toolAccess?.get("artifacts") &&
|
|
571
|
-
!access.toolAccess.get("artifacts").has("set_refresh")) {
|
|
572
|
-
throw new Error("Refresh owner no longer has refresh configuration access.");
|
|
573
|
-
}
|
|
574
|
-
if (access.guardedToolAccess?.get("artifacts")?.has("set_refresh")) {
|
|
575
|
-
throw new Error("A read-only guarded grant cannot configure refresh.");
|
|
576
|
-
}
|
|
577
|
-
access = intersectAccess(access, { connectorIds: sharedIds });
|
|
578
|
-
if (signal.aborted)
|
|
579
|
-
throw new Error("Refresh deadline expired before execution.");
|
|
580
|
-
const view = registry.scoped({ connectorIds: access.connectorIds,
|
|
581
|
-
...(access.toolAccess ? { toolAccess: access.toolAccess } : {}),
|
|
582
|
-
...(access.guardedToolAccess ? { guardedToolAccess: access.guardedToolAccess } : {}) });
|
|
583
|
-
const execute = createExecuteTool(view, config.publicUrl, executor, logger, undefined, refreshConfig);
|
|
584
|
-
return execute({ code: program }, { signal });
|
|
585
|
-
},
|
|
586
|
-
});
|
|
587
|
-
}
|
|
588
|
-
// Every structural check has passed, so this is the configuration the
|
|
589
|
-
// deployment runs with. Creating the runtime builds nothing — a Worker may
|
|
590
|
-
// construct its Connecta at global scope, where no fiber may start.
|
|
591
|
-
const runtime = createCoreRuntime(registry, {
|
|
592
|
-
storage,
|
|
593
|
-
logger,
|
|
594
|
-
vault: credentialVault,
|
|
595
|
-
activity: config.activity,
|
|
596
|
-
config: {
|
|
597
|
-
config,
|
|
598
|
-
serverInfo,
|
|
599
|
-
auth: inboundAuth,
|
|
600
|
-
pools,
|
|
601
|
-
executorName: configuredExecutorName,
|
|
602
|
-
},
|
|
211
|
+
// Built once, from values construction already validated; never per call.
|
|
212
|
+
const description = describeConfig({
|
|
213
|
+
registry,
|
|
214
|
+
raw: input,
|
|
215
|
+
config: resolved,
|
|
216
|
+
executorName: configuredExecutorName,
|
|
217
|
+
executorAdmits,
|
|
603
218
|
});
|
|
604
219
|
const handler = createFetchHandler({
|
|
220
|
+
config: resolved,
|
|
221
|
+
configDescription: description,
|
|
222
|
+
configValueSources: describeConfigSources(description, input),
|
|
605
223
|
registry,
|
|
606
|
-
auth: inboundAuth,
|
|
607
|
-
identity: config.identity,
|
|
608
224
|
pools,
|
|
609
|
-
publicUrl: config.publicUrl,
|
|
610
|
-
artifactOrigin: config.artifactOrigin,
|
|
611
|
-
allowedOrigins: config.allowedOrigins,
|
|
612
|
-
serverInfo,
|
|
613
|
-
logger,
|
|
614
|
-
activity: config.activity?.store,
|
|
615
|
-
activityModule: config.activity,
|
|
616
|
-
artifactsModule: config.artifacts,
|
|
617
|
-
accessTokens: config.accessTokens,
|
|
618
|
-
activityReadGate: config.activity?.readGate,
|
|
619
|
-
activityDeploymentId: config.activity?.deploymentId,
|
|
620
225
|
executor,
|
|
621
226
|
executorName: configuredExecutorName,
|
|
622
227
|
requestAdmission,
|
|
623
|
-
defaultToolTimeoutMs: config.calls?.defaultTimeoutMs,
|
|
624
|
-
probeTimeoutMs: config.discovery?.probeTimeoutMs,
|
|
625
|
-
discoveryConcurrency: config.discovery?.concurrency,
|
|
626
|
-
maxEmittedBytes: config.execute?.maxEmittedBytes,
|
|
627
|
-
maxEmittedBlocks: config.execute?.maxEmittedBlocks,
|
|
628
|
-
maxHostCalls: config.execute?.maxHostCalls,
|
|
629
|
-
hostCallTimeoutMs: config.execute?.hostCallTimeoutMs,
|
|
630
|
-
watchdogMs: config.execute?.watchdogMs,
|
|
631
|
-
approval,
|
|
632
|
-
maxWrites,
|
|
633
|
-
credentialVault,
|
|
634
|
-
ui: config.ui,
|
|
635
|
-
deploymentInfo: config.deploymentInfo,
|
|
636
|
-
branding: config.ui?.branding,
|
|
637
228
|
});
|
|
638
229
|
let closePromise;
|
|
639
230
|
return {
|
|
@@ -641,20 +232,13 @@ export function createConnecta(config) {
|
|
|
641
232
|
? ctx
|
|
642
233
|
: undefined),
|
|
643
234
|
registry,
|
|
235
|
+
describeConfig: () => description,
|
|
644
236
|
close: async () => {
|
|
645
237
|
closePromise ??= Promise.resolve().then(async () => {
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
await config.executor?.close?.();
|
|
651
|
-
}
|
|
652
|
-
finally {
|
|
653
|
-
// Last, and whether or not the executor closed cleanly. A fiber
|
|
654
|
-
// already running keeps the services it was given; only a run
|
|
655
|
-
// started after this is refused.
|
|
656
|
-
await disposeEdgeRuntime(runtime);
|
|
657
|
-
}
|
|
238
|
+
requestAdmission.close();
|
|
239
|
+
codeAdmission?.close();
|
|
240
|
+
registry.closeCallAdmission();
|
|
241
|
+
await resolved.executor.close?.();
|
|
658
242
|
});
|
|
659
243
|
await closePromise;
|
|
660
244
|
},
|
|
@@ -662,6 +246,8 @@ export function createConnecta(config) {
|
|
|
662
246
|
}
|
|
663
247
|
export { remoteMcp } from "./connectors/remote-mcp.js";
|
|
664
248
|
export { api } from "./connectors/api.js";
|
|
249
|
+
export { keys, optionsOf, array, opaque, instance, strings, variants } from "./config-schema.js";
|
|
250
|
+
export { defineProvider, PROVIDER_COMMON } from "./provider.js";
|
|
665
251
|
export { ConnectorCallError } from "./errors.js";
|
|
666
252
|
// The same argument validation api() performs, usable by connectors that
|
|
667
253
|
// implement the Connector interface directly. Returns the error rather than
|
|
@@ -669,3 +255,4 @@ export { ConnectorCallError } from "./errors.js";
|
|
|
669
255
|
export { validateToolInput } from "./validate.js";
|
|
670
256
|
export { memoryStorage } from "./storage/memory.js";
|
|
671
257
|
export { CONNECTA_VERSION } from "./version.js";
|
|
258
|
+
export { META_TOOL_NAMES } from "./meta-tool-names.js";
|