@zackbart/connecta 0.28.1 → 0.30.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 +855 -5
- package/README.md +125 -116
- package/bin/connecta.mjs +121 -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/argument-redaction.js +230 -0
- 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 +288 -0
- package/dist/authorization-handoff.js +111 -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 +409 -225
- 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 +633 -0
- package/dist/config.js +508 -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 +87 -38
- 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 +128 -0
- package/dist/downstream-input.js +325 -0
- package/dist/errors.d.ts +132 -31
- package/dist/errors.js +175 -87
- package/dist/execute.js +798 -318
- 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 +30 -13
- package/dist/executors/quickjs-child.js +15 -9
- package/dist/executors/quickjs-protocol.js +5 -6
- package/dist/executors/quickjs-runtime.js +152 -59
- package/dist/executors/quickjs.js +49 -39
- package/dist/favicon.js +1 -2
- package/dist/fix-prompt.js +1 -3
- package/dist/guest-runtime.js +238 -0
- package/dist/guest-types.d.ts +218 -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 +262 -79
- 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 +61 -0
- package/dist/meta-tool-names.d.ts +2 -0
- package/dist/meta-tool-names.js +3 -0
- package/dist/meta-tools.js +419 -272
- 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 +194 -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-result.js +5 -0
- package/dist/program-source.js +14 -2
- package/dist/{exempt-writes.js → program-writes.js} +60 -19
- 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/_shared/request-token.js +83 -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/infisical/index.d.ts +7 -0
- package/dist/providers/infisical/index.js +713 -0
- package/dist/providers/infisical/skill.generated.js +8 -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 +110 -171
- package/dist/registry.js +588 -927
- package/dist/request-state.js +21 -0
- package/dist/resource-read.js +103 -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 +365 -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 +93 -0
- package/dist/sent-secrets.js +1013 -0
- package/dist/server.js +28 -71
- package/dist/skills.js +416 -174
- package/dist/sqlite.d.ts +48 -0
- package/dist/sqlite.js +181 -0
- package/dist/storage/keys.js +443 -0
- package/dist/storage/memory.js +16 -4
- package/dist/storage/sql.d.ts +66 -0
- package/dist/storage/sql.js +543 -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 +336 -56
- 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 +146 -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 +435 -0
- package/documentation/README.md +63 -0
- package/documentation/architecture.md +696 -231
- package/documentation/auth.md +1069 -546
- package/documentation/code-mode.md +662 -356
- package/documentation/deploying.md +146 -0
- package/documentation/integrating.md +159 -0
- package/documentation/meta-tools.md +570 -216
- package/documentation/operating.md +135 -0
- package/documentation/operator-tests.md +97 -0
- package/documentation/operator-ui.md +132 -0
- package/documentation/provider-migration-0.29.md +65 -0
- package/examples/worker/AGENTS.md +34 -12
- package/examples/worker/README.md +293 -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 +126 -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 +140 -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
|
@@ -15,11 +15,13 @@ import { fork } from "node:child_process";
|
|
|
15
15
|
import { existsSync } from "node:fs";
|
|
16
16
|
import { fileURLToPath } from "node:url";
|
|
17
17
|
import { Deferred, Duration, Effect, Exit, Schedule, Scope } from "effect";
|
|
18
|
-
import { AdmissionController, ExecutorAdmissionError, ExecutorExecutionError
|
|
18
|
+
import { AdmissionController, ExecutorAdmissionError, ExecutorExecutionError } from "../executor-admission.js";
|
|
19
19
|
import { msg } from "../errors.js";
|
|
20
|
+
import { InvocationFailure } from "../invocation.js";
|
|
21
|
+
import { brandExecutor } from "../executor-contract.js";
|
|
20
22
|
import { MAX_EXECUTE_LOG_CHARS } from "../executor-result.js";
|
|
21
23
|
import { detach, fromSignal, runEdge } from "../runtime/run.js";
|
|
22
|
-
import { hostCallLabel, MAX_QUICKJS_IPC_BYTES, MAX_QUICKJS_HOST_RPC_BYTES, serializedBytes, stringifyBounded, } from "./quickjs-protocol.js";
|
|
24
|
+
import { hostCallLabel, MAX_QUICKJS_IPC_BYTES, MAX_QUICKJS_RESULT_BYTES, QUICKJS_RESULT_CHUNK_CHARS, MAX_QUICKJS_HOST_RPC_BYTES, serializedBytes, stringifyBounded, } from "./quickjs-protocol.js";
|
|
23
25
|
export { normalizeCode } from "./quickjs-runtime.js";
|
|
24
26
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
25
27
|
const DEFAULT_CPU_TIME_MS = 250;
|
|
@@ -36,10 +38,7 @@ const MAX_CHILD_STDERR_BYTES = 8 * 1024;
|
|
|
36
38
|
const MAX_ERROR_CHARS = 4_000;
|
|
37
39
|
// Respawn backoff after consecutive crashes: 100 ms, doubling, capped at 5 s.
|
|
38
40
|
// A value, not a running effect: stepping it happens inside a request's fiber.
|
|
39
|
-
const CRASH_BACKOFF = Schedule.min([
|
|
40
|
-
Schedule.exponential(Duration.millis(100)),
|
|
41
|
-
Schedule.spaced(Duration.seconds(5)),
|
|
42
|
-
]);
|
|
41
|
+
const CRASH_BACKOFF = Schedule.min([Schedule.exponential(Duration.millis(100)), Schedule.spaced(Duration.seconds(5))]);
|
|
43
42
|
const crashBackoff = Effect.map(Schedule.toStep(CRASH_BACKOFF), (step) => (crashedAt) => step(crashedAt, undefined).pipe(Effect.map(([, delay]) => crashedAt + Duration.toMillis(delay)),
|
|
44
43
|
// Neither schedule ever halts; a halt here would be a broken invariant.
|
|
45
44
|
Effect.orDie));
|
|
@@ -56,36 +55,27 @@ function retainStderrTail(current, chunk) {
|
|
|
56
55
|
function childExitError(message, stderrTail) {
|
|
57
56
|
if (stderrTail.length === 0)
|
|
58
57
|
return new Error(message);
|
|
59
|
-
return new Error(`${message}\nRecent child stderr (last ${stderrTail.length} bytes):\n` +
|
|
60
|
-
stderrTail.toString("utf8"));
|
|
58
|
+
return new Error(`${message}\nRecent child stderr (last ${stderrTail.length} bytes):\n` + stderrTail.toString("utf8"));
|
|
61
59
|
}
|
|
62
60
|
function positiveWhole(value, fallback, name) {
|
|
63
61
|
const resolved = value ?? fallback;
|
|
64
|
-
if (!Number.isFinite(resolved) ||
|
|
65
|
-
!Number.isInteger(resolved) ||
|
|
66
|
-
resolved < 1) {
|
|
62
|
+
if (!Number.isFinite(resolved) || !Number.isInteger(resolved) || resolved < 1) {
|
|
67
63
|
throw new TypeError(`${name} must be a positive whole number.`);
|
|
68
64
|
}
|
|
69
65
|
return resolved;
|
|
70
66
|
}
|
|
71
67
|
function nonNegativeWhole(value, fallback, name) {
|
|
72
68
|
const resolved = value ?? fallback;
|
|
73
|
-
if (!Number.isFinite(resolved) ||
|
|
74
|
-
!Number.isInteger(resolved) ||
|
|
75
|
-
resolved < 0) {
|
|
69
|
+
if (!Number.isFinite(resolved) || !Number.isInteger(resolved) || resolved < 0) {
|
|
76
70
|
throw new TypeError(`${name} must be a non-negative whole number.`);
|
|
77
71
|
}
|
|
78
72
|
return resolved;
|
|
79
73
|
}
|
|
80
74
|
function errorPayload(error) {
|
|
81
|
-
// X11: a partial authenticated frame exposes its secret instead of decoding.
|
|
82
|
-
// Refuse it whole if a host ever bypasses execute.ts's framing bound.
|
|
83
|
-
const message = error.length > MAX_ERROR_CHARS && error.includes("\u001econnecta-error:")
|
|
84
|
-
? `Host failure exceeded the ${MAX_ERROR_CHARS}-character bridge limit.`
|
|
85
|
-
: error.slice(0, MAX_ERROR_CHARS);
|
|
86
75
|
return JSON.stringify({
|
|
87
76
|
ok: false,
|
|
88
|
-
error:
|
|
77
|
+
error: msg(error).slice(0, MAX_ERROR_CHARS),
|
|
78
|
+
...(error instanceof InvocationFailure ? { call: error.details } : {}),
|
|
89
79
|
});
|
|
90
80
|
}
|
|
91
81
|
function cancelled(message) {
|
|
@@ -104,10 +94,7 @@ function unlessCancelled(effect, signal, message) {
|
|
|
104
94
|
return effect;
|
|
105
95
|
if (signal.aborted)
|
|
106
96
|
return Effect.fail(cancelled(message));
|
|
107
|
-
return Effect.raceAllFirst([
|
|
108
|
-
effect,
|
|
109
|
-
fromSignal(signal).pipe(Effect.mapError(() => cancelled(message))),
|
|
110
|
-
]);
|
|
97
|
+
return Effect.raceAllFirst([effect, fromSignal(signal).pipe(Effect.mapError(() => cancelled(message)))]);
|
|
111
98
|
}
|
|
112
99
|
/**
|
|
113
100
|
* The child's release: SIGTERM, then wait for the exit, bounded — a child
|
|
@@ -257,6 +244,8 @@ class QuickJsChildPool {
|
|
|
257
244
|
id,
|
|
258
245
|
logs: [],
|
|
259
246
|
logChars: 0,
|
|
247
|
+
resultChunks: [],
|
|
248
|
+
resultBytes: 0,
|
|
260
249
|
providers: providerMap,
|
|
261
250
|
outcome: Deferred.makeUnsafe(),
|
|
262
251
|
};
|
|
@@ -282,9 +271,19 @@ class QuickJsChildPool {
|
|
|
282
271
|
this.rejectActive(slot, error);
|
|
283
272
|
this.recycle(slot);
|
|
284
273
|
}).pipe(Effect.andThen(Effect.never));
|
|
274
|
+
const started = Date.now();
|
|
285
275
|
const contenders = [
|
|
286
276
|
Deferred.await(active.outcome),
|
|
287
|
-
Effect.sleep(Duration.millis(this.runtimeOptions.timeoutMs + CHILD_EXIT_GRACE_MS)).pipe(Effect.andThen(
|
|
277
|
+
Effect.sleep(Duration.millis(this.runtimeOptions.timeoutMs + CHILD_EXIT_GRACE_MS)).pipe(Effect.andThen(Effect.suspend(() => {
|
|
278
|
+
const elapsedMs = Date.now() - started;
|
|
279
|
+
const deadlineMs = this.runtimeOptions.timeoutMs;
|
|
280
|
+
return endWith(new InvocationFailure({
|
|
281
|
+
code: "timeout",
|
|
282
|
+
message: `Operation "execute_code" timed out during sandbox termination after ${elapsedMs}ms (effective deadline ${deadlineMs}ms).`,
|
|
283
|
+
retryable: false,
|
|
284
|
+
details: { operation: "execute_code", stage: "sandbox termination", elapsedMs, deadlineMs },
|
|
285
|
+
}));
|
|
286
|
+
}))),
|
|
288
287
|
];
|
|
289
288
|
if (signal) {
|
|
290
289
|
contenders.push(fromSignal(signal).pipe(Effect.catch(() => endWith(cancelled("Execution was cancelled.")))));
|
|
@@ -448,7 +447,9 @@ class QuickJsChildPool {
|
|
|
448
447
|
active.logs.push(retained);
|
|
449
448
|
active.logChars += separator + retained.length;
|
|
450
449
|
}
|
|
451
|
-
catch {
|
|
450
|
+
catch {
|
|
451
|
+
/* Malformed log messages carry no output. */
|
|
452
|
+
}
|
|
452
453
|
return;
|
|
453
454
|
}
|
|
454
455
|
if (message.type === "host-call") {
|
|
@@ -457,15 +458,29 @@ class QuickJsChildPool {
|
|
|
457
458
|
await this.handleHostCall(slot, child.process, active, message);
|
|
458
459
|
return;
|
|
459
460
|
}
|
|
460
|
-
if (message.type !== "result" || message.jobId !== active.id)
|
|
461
|
+
if ((message.type !== "result" && message.type !== "result-chunk") || message.jobId !== active.id)
|
|
461
462
|
return;
|
|
462
|
-
if (
|
|
463
|
+
if (message.payloadJson.length > QUICKJS_RESULT_CHUNK_CHARS ||
|
|
464
|
+
(message.type === "result-chunk" && message.payloadJson.length !== QUICKJS_RESULT_CHUNK_CHARS) ||
|
|
465
|
+
message.payloadJson.length === 0) {
|
|
466
|
+
this.rejectActive(slot, new Error("QuickJS execution result exceeded the IPC limit."));
|
|
467
|
+
this.recycle(slot);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const bytes = serializedBytes(message.payloadJson);
|
|
471
|
+
if (active.resultBytes + bytes > MAX_QUICKJS_RESULT_BYTES) {
|
|
463
472
|
this.rejectActive(slot, new Error("QuickJS execution result exceeded the IPC limit."));
|
|
464
473
|
this.recycle(slot);
|
|
465
474
|
return;
|
|
466
475
|
}
|
|
467
476
|
try {
|
|
468
|
-
|
|
477
|
+
stringifyBounded(message, "QuickJS result IPC envelope");
|
|
478
|
+
active.resultBytes += bytes;
|
|
479
|
+
active.resultChunks.push(message.payloadJson);
|
|
480
|
+
if (message.type === "result-chunk")
|
|
481
|
+
return;
|
|
482
|
+
const payload = JSON.parse(active.resultChunks.join(""));
|
|
483
|
+
active.resultChunks.length = 0;
|
|
469
484
|
// A result ends any crash streak: the next crash backs off from 100 ms.
|
|
470
485
|
slot.crashes.length = 0;
|
|
471
486
|
slot.backoff = undefined;
|
|
@@ -487,8 +502,7 @@ class QuickJsChildPool {
|
|
|
487
502
|
async handleHostCall(slot, child, active, message) {
|
|
488
503
|
let payloadJson;
|
|
489
504
|
try {
|
|
490
|
-
if (serializedBytes(message.payloadJson) >
|
|
491
|
-
MAX_QUICKJS_HOST_RPC_BYTES) {
|
|
505
|
+
if (serializedBytes(message.payloadJson) > MAX_QUICKJS_HOST_RPC_BYTES) {
|
|
492
506
|
// Refused before parsing, so there is no address to name here: parsing
|
|
493
507
|
// an over-limit payload to improve its error message would spend the
|
|
494
508
|
// work the limit exists to refuse.
|
|
@@ -496,9 +510,7 @@ class QuickJsChildPool {
|
|
|
496
510
|
}
|
|
497
511
|
const payload = JSON.parse(message.payloadJson);
|
|
498
512
|
const provider = active.providers.get(payload.namespace);
|
|
499
|
-
const fn = provider && Object.hasOwn(provider.fns, payload.functionName)
|
|
500
|
-
? provider.fns[payload.functionName]
|
|
501
|
-
: undefined;
|
|
513
|
+
const fn = provider && Object.hasOwn(provider.fns, payload.functionName) ? provider.fns[payload.functionName] : undefined;
|
|
502
514
|
if (!fn) {
|
|
503
515
|
throw new Error(`Unknown function ${payload.namespace}.${payload.functionName}`);
|
|
504
516
|
}
|
|
@@ -517,7 +529,7 @@ class QuickJsChildPool {
|
|
|
517
529
|
}
|
|
518
530
|
}
|
|
519
531
|
catch (err) {
|
|
520
|
-
payloadJson = errorPayload(
|
|
532
|
+
payloadJson = errorPayload(err);
|
|
521
533
|
}
|
|
522
534
|
if (!child.connected || slot.active !== active)
|
|
523
535
|
return;
|
|
@@ -554,9 +566,7 @@ class QuickJsChildPool {
|
|
|
554
566
|
return;
|
|
555
567
|
// Never concatenate the stream with the final reply: those entries are
|
|
556
568
|
// the same logs. A normal reply retains its existing full log contract.
|
|
557
|
-
const resolved = outcome.logs === undefined && active.logs.length > 0
|
|
558
|
-
? { ...outcome, logs: active.logs }
|
|
559
|
-
: outcome;
|
|
569
|
+
const resolved = outcome.logs === undefined && active.logs.length > 0 ? { ...outcome, logs: active.logs } : outcome;
|
|
560
570
|
this.clearActive(slot);
|
|
561
571
|
Deferred.doneUnsafe(active.outcome, Exit.succeed(resolved));
|
|
562
572
|
}
|
|
@@ -621,5 +631,5 @@ class QuickJsChildPool {
|
|
|
621
631
|
* double-acquire deadlock at concurrency 1.
|
|
622
632
|
*/
|
|
623
633
|
export function quickJsExecutor(options = {}) {
|
|
624
|
-
return new QuickJsChildPool(options);
|
|
634
|
+
return brandExecutor(new QuickJsChildPool(options), "leased");
|
|
625
635
|
}
|
package/dist/favicon.js
CHANGED
|
@@ -32,8 +32,7 @@ function buildIco() {
|
|
|
32
32
|
const dx = x - 15.5;
|
|
33
33
|
const dy = y - 15.5;
|
|
34
34
|
const radius = Math.sqrt(dx * dx + dy * dy);
|
|
35
|
-
const opaque = radius >= 8 && radius <= 13 &&
|
|
36
|
-
(x <= 18 || Math.abs(dy) >= 7);
|
|
35
|
+
const opaque = radius >= 8 && radius <= 13 && (x <= 18 || Math.abs(dy) >= 7);
|
|
37
36
|
const row = size - 1 - y;
|
|
38
37
|
const pixel = pixels + (row * size + x) * 4;
|
|
39
38
|
ico[pixel + 3] = opaque ? 255 : 0;
|
package/dist/fix-prompt.js
CHANGED
|
@@ -18,9 +18,7 @@ const CONNECTOR_ID_RE = /^[a-z0-9_-]+$/;
|
|
|
18
18
|
* than escaped, since a value that is not a connector id is not config.
|
|
19
19
|
*/
|
|
20
20
|
export function renderFixPrompt(spec, connectorId) {
|
|
21
|
-
const id = connectorId !== undefined && CONNECTOR_ID_RE.test(connectorId)
|
|
22
|
-
? connectorId
|
|
23
|
-
: undefined;
|
|
21
|
+
const id = connectorId !== undefined && CONNECTOR_ID_RE.test(connectorId) ? connectorId : undefined;
|
|
24
22
|
return [
|
|
25
23
|
"Diagnose and fix a problem in this connecta deployment (the @zackbart/connecta package). " +
|
|
26
24
|
"It is configured as code: connectors, credential slots, OAuth clients, pools, and inbound auth " +
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
/** Capture the single-use runner before evaluating the guest expression. */
|
|
2
|
+
export function wrapGuestProgram(code) {
|
|
3
|
+
return `async () => globalThis.__connecta_run()(async (connecta) => await (\n${code}\n)())`;
|
|
4
|
+
}
|
|
5
|
+
/** Separate user source from the trusted wrapper before publishing Worker modules. */
|
|
6
|
+
export function isolateGuestProgram(code) {
|
|
7
|
+
const prefix = "async () => globalThis.__connecta_run()(";
|
|
8
|
+
const callback = "async (connecta) => await (\n";
|
|
9
|
+
const suffix = "\n)())";
|
|
10
|
+
if (!code.startsWith(prefix + callback) || !code.endsWith(suffix))
|
|
11
|
+
return undefined;
|
|
12
|
+
return {
|
|
13
|
+
program: code.slice(prefix.length, -1),
|
|
14
|
+
// Only this fixed wrapper enters the private runner module. Matching text
|
|
15
|
+
// inside an arbitrary body/string is guest data, never a trusted wrapper.
|
|
16
|
+
wrapper: `${prefix}__connecta_user_program)`,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Emissions are acknowledged before success, even when the guest omits await.
|
|
21
|
+
* Capture intrinsics before user code can replace them.
|
|
22
|
+
*/
|
|
23
|
+
export function guestPrelude() {
|
|
24
|
+
return `${guestInitializer()}(connecta);`;
|
|
25
|
+
}
|
|
26
|
+
/** Protect completion promises before any Worker or QuickJS guest runs. */
|
|
27
|
+
export function guestPromiseInitializer() {
|
|
28
|
+
return `(() => {
|
|
29
|
+
const NativePromise = Promise;
|
|
30
|
+
const nativeResolve = Function.prototype.call.bind(NativePromise.resolve);
|
|
31
|
+
const nativeRace = Function.prototype.call.bind(NativePromise.race);
|
|
32
|
+
const isArray = Array.isArray;
|
|
33
|
+
const iteratorKey = Symbol.iterator;
|
|
34
|
+
const arrayValues = Function.prototype.call.bind(Array.prototype.values);
|
|
35
|
+
const arrayNext = Function.prototype.call.bind(Object.getPrototypeOf([][Symbol.iterator]()).next);
|
|
36
|
+
function safeRace(values) {
|
|
37
|
+
// Upstream constructs its completion array after the program starts.
|
|
38
|
+
// Use captured array iteration, with private own methods, so neither a
|
|
39
|
+
// replaced iterator factory nor iterator.next can observe its promises.
|
|
40
|
+
if (isArray(values)) {
|
|
41
|
+
const iterator = arrayValues(values);
|
|
42
|
+
values = { __proto__: null, [iteratorKey]: () => ({ __proto__: null,
|
|
43
|
+
next: () => arrayNext(iterator) }) };
|
|
44
|
+
}
|
|
45
|
+
return nativeRace(HostPromise, values);
|
|
46
|
+
}
|
|
47
|
+
// The upstream Worker starts its Promise.race after invoking the program.
|
|
48
|
+
// Its deadline must not use a resolve function replaced during that invocation.
|
|
49
|
+
class HostPromise extends NativePromise {}
|
|
50
|
+
Object.defineProperties(HostPromise, {
|
|
51
|
+
resolve: { value: value => nativeResolve(HostPromise, value) },
|
|
52
|
+
[Symbol.species]: { value: HostPromise }
|
|
53
|
+
});
|
|
54
|
+
Object.freeze(HostPromise.prototype);
|
|
55
|
+
Object.freeze(HostPromise);
|
|
56
|
+
Object.defineProperties(NativePromise, {
|
|
57
|
+
race: { value: safeRace, writable: false, configurable: false },
|
|
58
|
+
[Symbol.species]: { value: NativePromise, configurable: false }
|
|
59
|
+
});
|
|
60
|
+
// Async return values are adopted through their prototype's then method.
|
|
61
|
+
// Guest callbacks must not change host completion.
|
|
62
|
+
Object.freeze(NativePromise.prototype);
|
|
63
|
+
})()`;
|
|
64
|
+
}
|
|
65
|
+
/** Capture a private initializer before a Worker evaluates its guest module. */
|
|
66
|
+
export function guestInitializer() {
|
|
67
|
+
return `(() => {
|
|
68
|
+
${guestPromiseInitializer()};
|
|
69
|
+
const NativePromise = Promise;
|
|
70
|
+
const freeze = Object.freeze;
|
|
71
|
+
const defineProperties = Object.defineProperties;
|
|
72
|
+
// Protect the bridge codec and its object prototypes from guest hooks.
|
|
73
|
+
freeze(JSON);
|
|
74
|
+
freeze(Object.prototype);
|
|
75
|
+
defineProperties(globalThis, {
|
|
76
|
+
JSON: { value: JSON, writable: false, configurable: false },
|
|
77
|
+
Promise: { value: NativePromise, writable: false, configurable: false }
|
|
78
|
+
});
|
|
79
|
+
const promiseThen = Function.prototype.call.bind(NativePromise.prototype.then);
|
|
80
|
+
const promiseCatch = Function.prototype.call.bind(NativePromise.prototype.catch);
|
|
81
|
+
const promiseFinally = Function.prototype.call.bind(NativePromise.prototype.finally);
|
|
82
|
+
const push = Function.prototype.call.bind(Array.prototype.push);
|
|
83
|
+
const apply = Function.prototype.call.bind(Function.prototype.apply);
|
|
84
|
+
const NativeError = Error;
|
|
85
|
+
const NativeWeakMap = WeakMap;
|
|
86
|
+
const isArray = Array.isArray;
|
|
87
|
+
const weakGet = Function.prototype.call.bind(WeakMap.prototype.get);
|
|
88
|
+
const weakSet = Function.prototype.call.bind(WeakMap.prototype.set);
|
|
89
|
+
return freeze((provider) => {
|
|
90
|
+
const pending = [];
|
|
91
|
+
const emit = provider.emit;
|
|
92
|
+
const hostCall = provider.call;
|
|
93
|
+
const hostResult = provider.result;
|
|
94
|
+
const nativeRefs = new NativeWeakMap();
|
|
95
|
+
async function inline(value) {
|
|
96
|
+
if (!value || typeof value.transfer !== "string" || !value.handle) return value;
|
|
97
|
+
// A completed downstream call stays successful if transfer storage fails.
|
|
98
|
+
// Preserve its handle so the caller can page later, without repeating a write.
|
|
99
|
+
try {
|
|
100
|
+
let text = "", page;
|
|
101
|
+
do {
|
|
102
|
+
page = await hostResult(value.transfer);
|
|
103
|
+
text += page.text;
|
|
104
|
+
} while (page.hasMore);
|
|
105
|
+
return { data: value.handle.valueFormat === "json" ? JSON.parse(text) : text,
|
|
106
|
+
format: value.handle.valueFormat };
|
|
107
|
+
} catch { return value.handle; }
|
|
108
|
+
}
|
|
109
|
+
async function call() {
|
|
110
|
+
const reply = await apply(hostCall, undefined, arguments);
|
|
111
|
+
if (!reply || !reply.native) return inline(reply);
|
|
112
|
+
const native = await inline(reply.native.value);
|
|
113
|
+
if (native.format === "paged" && !reply.value) return native;
|
|
114
|
+
const value = reply.value ? await inline(reply.value) : {
|
|
115
|
+
data: reply.native.dataKey ? native.data[reply.native.dataKey] : native.data, format: "json"
|
|
116
|
+
};
|
|
117
|
+
if (value.format === "paged") return value;
|
|
118
|
+
if (native.format === "paged") {
|
|
119
|
+
value.contentResult = native;
|
|
120
|
+
return value;
|
|
121
|
+
}
|
|
122
|
+
if (native.format === "json" && native.data && isArray(native.data.content)) {
|
|
123
|
+
const content = native.data.content;
|
|
124
|
+
// Only host-issued refs cross back. Binary data never needs a second
|
|
125
|
+
// guest-to-host transfer, and guest edits cannot mint native pointers.
|
|
126
|
+
for (let i = 0; i < content.length; i++) {
|
|
127
|
+
weakSet(nativeRefs, content[i], { ref: reply.native.ref, index: i });
|
|
128
|
+
}
|
|
129
|
+
value.content = content;
|
|
130
|
+
weakSet(nativeRefs, value, { ref: reply.native.ref });
|
|
131
|
+
}
|
|
132
|
+
return value;
|
|
133
|
+
}
|
|
134
|
+
function trackEmission(task) {
|
|
135
|
+
const entry = { handled: false, settled: promiseThen(task,
|
|
136
|
+
() => ({ ok: true }), error => ({ ok: false, error })) };
|
|
137
|
+
push(pending, entry);
|
|
138
|
+
// Every derived promise owns propagated rejection; only an unhandled
|
|
139
|
+
// leaf fails the run, so a later catch also handles its ancestors.
|
|
140
|
+
return freeze({
|
|
141
|
+
then(resolve, reject) {
|
|
142
|
+
entry.handled = true;
|
|
143
|
+
return trackEmission(promiseThen(task, resolve, reject));
|
|
144
|
+
},
|
|
145
|
+
catch(reject) {
|
|
146
|
+
entry.handled = true;
|
|
147
|
+
return trackEmission(promiseCatch(task, reject));
|
|
148
|
+
},
|
|
149
|
+
finally(callback) {
|
|
150
|
+
entry.handled = true;
|
|
151
|
+
return trackEmission(promiseFinally(task, callback));
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
const namespace = freeze({
|
|
156
|
+
__proto__: null,
|
|
157
|
+
search: provider.search,
|
|
158
|
+
describe: provider.describe,
|
|
159
|
+
call,
|
|
160
|
+
read: provider.read,
|
|
161
|
+
result: provider.result,
|
|
162
|
+
skill: provider.skill,
|
|
163
|
+
emit(block) {
|
|
164
|
+
const ref = block && typeof block === "object" ? weakGet(nativeRefs, block) : undefined;
|
|
165
|
+
return trackEmission(emit(ref || block));
|
|
166
|
+
}
|
|
167
|
+
});
|
|
168
|
+
globalThis.connecta = namespace;
|
|
169
|
+
defineProperties(globalThis, {
|
|
170
|
+
Error: { value: NativeError, writable: false, configurable: false },
|
|
171
|
+
__connecta_run: { configurable: true, value: () => {
|
|
172
|
+
delete globalThis.__connecta_run;
|
|
173
|
+
let used = false;
|
|
174
|
+
return async (program) => {
|
|
175
|
+
if (used) throw new NativeError("Guest runner initialization is single-use.");
|
|
176
|
+
used = true;
|
|
177
|
+
const result = await program(namespace);
|
|
178
|
+
for (let i = 0; i < pending.length; i++) {
|
|
179
|
+
const report = await pending[i].settled;
|
|
180
|
+
if (!report.ok && !pending[i].handled) throw report.error;
|
|
181
|
+
}
|
|
182
|
+
return result;
|
|
183
|
+
};
|
|
184
|
+
}}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
})()`;
|
|
188
|
+
}
|
|
189
|
+
const ERROR_NAMES = new Set([
|
|
190
|
+
"Error",
|
|
191
|
+
"TypeError",
|
|
192
|
+
"SyntaxError",
|
|
193
|
+
"ReferenceError",
|
|
194
|
+
"RangeError",
|
|
195
|
+
"EvalError",
|
|
196
|
+
"URIError",
|
|
197
|
+
"AggregateError",
|
|
198
|
+
]);
|
|
199
|
+
/** Fixed repair guidance, used only in agent-facing results. */
|
|
200
|
+
export function programError(raw, code) {
|
|
201
|
+
const message = typeof raw.message === "string" ? raw.message : "Program failed.";
|
|
202
|
+
const name = typeof raw.name === "string" && ERROR_NAMES.has(raw.name) ? raw.name : "Error";
|
|
203
|
+
const stack = typeof raw.stack === "string" ? raw.stack : "";
|
|
204
|
+
// Compare QuickJS/V8 locations to the wrapper baseline after the source.
|
|
205
|
+
const location = /:(\d+)(?::\d+)?\)?(?:\n|$)/.exec(stack);
|
|
206
|
+
const baseline = typeof raw.baseline === "string" ? /:(\d+)(?::\d+)?\)?(?:\n|$)/.exec(raw.baseline) : null;
|
|
207
|
+
// Workers publish only the user callback in this module, with one prefix line.
|
|
208
|
+
// Its trusted wrapper and baseline live in a separate, private module scope.
|
|
209
|
+
const workerLocation = /connecta-guest\.js:(\d+):\d+/.exec(stack);
|
|
210
|
+
const line = typeof raw.line === "number" && Number.isFinite(raw.line)
|
|
211
|
+
? Math.max(1, raw.line)
|
|
212
|
+
: workerLocation
|
|
213
|
+
? Math.max(1, Number(workerLocation[1]) - 1)
|
|
214
|
+
: location && baseline
|
|
215
|
+
? Math.max(1, Number(location[1]) - Number(baseline[1]) + code.split("\n").length + 1)
|
|
216
|
+
: null;
|
|
217
|
+
let hint = "Use plain JavaScript in one async () => { ... } expression and the connecta global.";
|
|
218
|
+
if (/\brequire\b|\b[Ii]mports?\b|\bfs\b|filesystem|node:/.test(message) ||
|
|
219
|
+
(name === "SyntaxError" && /\bimport\b/.test(code))) {
|
|
220
|
+
hint =
|
|
221
|
+
"Imports, require, and filesystem access are outside the guest API. Use connecta.call to access configured services.";
|
|
222
|
+
}
|
|
223
|
+
else if (["TypeError", "ReferenceError"].includes(name) &&
|
|
224
|
+
/(?:const|let|var|function|\()\s*connecta\b/.test(code)) {
|
|
225
|
+
hint = "Do not shadow connecta. Use the host-provided connecta global.";
|
|
226
|
+
}
|
|
227
|
+
else if (/callTool|mixpanel|\bskills\b|connecta\.(?:guide|skills)/.test(message) ||
|
|
228
|
+
(["TypeError", "ReferenceError"].includes(name) && /connecta\.(?:guide|skills)\b/.test(code))) {
|
|
229
|
+
hint =
|
|
230
|
+
"Use connecta.call(address, args), connecta.search, connecta.describe, connecta.result, and connecta.skill(name). Services are addressed by connector.tool, never guest globals.";
|
|
231
|
+
}
|
|
232
|
+
return {
|
|
233
|
+
code: "program_error",
|
|
234
|
+
message: `Program ${name}: ${message}`,
|
|
235
|
+
retryable: false,
|
|
236
|
+
details: { name, line, hint },
|
|
237
|
+
};
|
|
238
|
+
}
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import type { ToolDef } from "./types.js";
|
|
2
|
+
import type { CallErrorDetails } from "./errors.js";
|
|
3
|
+
/** TypeScript notation for the JavaScript guest global; programs receive no arguments. */
|
|
4
|
+
export interface GuestApi {
|
|
5
|
+
search(args?: CatalogSearchArgs): Promise<CatalogSearchResult>;
|
|
6
|
+
describe(args?: CatalogDescribeArgs): Promise<{
|
|
7
|
+
tools: CatalogDescription[];
|
|
8
|
+
}>;
|
|
9
|
+
call(address: string, args?: unknown, options?: {
|
|
10
|
+
timeoutMs?: number;
|
|
11
|
+
}): Promise<GuestResult>;
|
|
12
|
+
call(request: {
|
|
13
|
+
address: string;
|
|
14
|
+
args?: unknown;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
}): Promise<GuestResult>;
|
|
17
|
+
read(uri: string): Promise<GuestResourceResult>;
|
|
18
|
+
result(id: string | GuestResultHandle, options?: {
|
|
19
|
+
page?: number;
|
|
20
|
+
offset?: number;
|
|
21
|
+
maxBytes?: number;
|
|
22
|
+
}): Promise<GuestResultPage>;
|
|
23
|
+
skill(name: string): Promise<{
|
|
24
|
+
name: string;
|
|
25
|
+
text: string;
|
|
26
|
+
format: "text";
|
|
27
|
+
}>;
|
|
28
|
+
emit(block: GuestNativeBlock | GuestResult): PromiseLike<void>;
|
|
29
|
+
}
|
|
30
|
+
export interface GuestResourceResult {
|
|
31
|
+
contents: Array<{
|
|
32
|
+
uri: string;
|
|
33
|
+
mimeType?: string;
|
|
34
|
+
} & ({
|
|
35
|
+
text: string;
|
|
36
|
+
} | {
|
|
37
|
+
blob: string;
|
|
38
|
+
})>;
|
|
39
|
+
}
|
|
40
|
+
export interface GuestResultHandle {
|
|
41
|
+
format: "paged";
|
|
42
|
+
valueFormat: "json" | "text";
|
|
43
|
+
resultId?: string;
|
|
44
|
+
totalBytes: number;
|
|
45
|
+
truncated: true;
|
|
46
|
+
hint: string;
|
|
47
|
+
}
|
|
48
|
+
/** Inline MCP rich results expose original blocks; emit(result) forwards all of them. */
|
|
49
|
+
export type GuestResult = ({
|
|
50
|
+
data: unknown;
|
|
51
|
+
format: "json";
|
|
52
|
+
} | {
|
|
53
|
+
data: string;
|
|
54
|
+
format: "text";
|
|
55
|
+
} | GuestResultHandle) & {
|
|
56
|
+
content?: GuestNativeBlock[];
|
|
57
|
+
/** Paging handle when native content exceeds the inline cap or transfer fails. */
|
|
58
|
+
contentResult?: GuestResultHandle;
|
|
59
|
+
};
|
|
60
|
+
/** Native call blocks can be forwarded unchanged, including annotations and metadata. */
|
|
61
|
+
export type GuestNativeBlock = (GuestBlock | {
|
|
62
|
+
type: "resource";
|
|
63
|
+
resource: {
|
|
64
|
+
uri: string;
|
|
65
|
+
mimeType?: string;
|
|
66
|
+
} & ({
|
|
67
|
+
text: string;
|
|
68
|
+
} | {
|
|
69
|
+
blob: string;
|
|
70
|
+
});
|
|
71
|
+
} | {
|
|
72
|
+
type: "resource_link";
|
|
73
|
+
uri: string;
|
|
74
|
+
name: string;
|
|
75
|
+
title?: string;
|
|
76
|
+
description?: string;
|
|
77
|
+
mimeType?: string;
|
|
78
|
+
size?: number;
|
|
79
|
+
}) & {
|
|
80
|
+
annotations?: {
|
|
81
|
+
audience?: Array<"user" | "assistant">;
|
|
82
|
+
priority?: number;
|
|
83
|
+
lastModified?: string;
|
|
84
|
+
};
|
|
85
|
+
_meta?: Record<string, unknown>;
|
|
86
|
+
};
|
|
87
|
+
export interface GuestResultPage {
|
|
88
|
+
resultId: string;
|
|
89
|
+
offset: number;
|
|
90
|
+
bytes: number;
|
|
91
|
+
totalBytes: number;
|
|
92
|
+
hasMore: boolean;
|
|
93
|
+
nextOffset?: number;
|
|
94
|
+
format: "text";
|
|
95
|
+
text: string;
|
|
96
|
+
}
|
|
97
|
+
export type GuestBlock = {
|
|
98
|
+
type: "text";
|
|
99
|
+
text: string;
|
|
100
|
+
} | {
|
|
101
|
+
type: "image" | "audio";
|
|
102
|
+
data: string;
|
|
103
|
+
mimeType: string;
|
|
104
|
+
};
|
|
105
|
+
type SchemaFormat = "json" | "compact" | "typescript";
|
|
106
|
+
export interface CatalogSearchArgs {
|
|
107
|
+
query?: string;
|
|
108
|
+
connector?: string;
|
|
109
|
+
safety?: "readOnly" | "approvalRequired" | "all";
|
|
110
|
+
limit?: number;
|
|
111
|
+
offset?: number;
|
|
112
|
+
fullDescriptions?: boolean;
|
|
113
|
+
includeSchemas?: SchemaFormat;
|
|
114
|
+
includeSchemaKeys?: boolean;
|
|
115
|
+
}
|
|
116
|
+
export interface CatalogDescribeArgs {
|
|
117
|
+
address?: unknown;
|
|
118
|
+
addresses?: unknown;
|
|
119
|
+
format?: SchemaFormat;
|
|
120
|
+
fullDescriptions?: boolean;
|
|
121
|
+
}
|
|
122
|
+
type GuideRequiredReason = "connector_required" | "approval_required" | "schema_truncated";
|
|
123
|
+
interface CatalogFailureDetail extends Partial<import("./errors.js").AuthorizationHandoff> {
|
|
124
|
+
nextAction?: CallErrorDetails["nextAction"];
|
|
125
|
+
retry?: string;
|
|
126
|
+
code: string;
|
|
127
|
+
message: string;
|
|
128
|
+
retryable: boolean;
|
|
129
|
+
retryAfterMs?: number;
|
|
130
|
+
}
|
|
131
|
+
interface CatalogDescriptionFailureDetail extends CatalogFailureDetail {
|
|
132
|
+
configuredConnectors?: string[];
|
|
133
|
+
nextAction?: NonNullable<CallErrorDetails["nextAction"]>;
|
|
134
|
+
suggestions?: string[];
|
|
135
|
+
}
|
|
136
|
+
interface CatalogSearchFailure extends CatalogFailureDetail {
|
|
137
|
+
connector: string;
|
|
138
|
+
nextAction?: Extract<NonNullable<CallErrorDetails["nextAction"]>, {
|
|
139
|
+
tool: "authorize_connector";
|
|
140
|
+
}>;
|
|
141
|
+
retry?: string;
|
|
142
|
+
}
|
|
143
|
+
export interface CatalogSearchPage {
|
|
144
|
+
catalogErrors: CatalogSearchFailure[];
|
|
145
|
+
absence?: {
|
|
146
|
+
service: string;
|
|
147
|
+
message: string;
|
|
148
|
+
configuredConnectors: string[];
|
|
149
|
+
};
|
|
150
|
+
total: number;
|
|
151
|
+
offset: number;
|
|
152
|
+
limit: number;
|
|
153
|
+
hasMore: boolean;
|
|
154
|
+
nextOffset?: number;
|
|
155
|
+
matchMode?: "partial";
|
|
156
|
+
queryAnalysis?: {
|
|
157
|
+
representedTerms: string[];
|
|
158
|
+
otherResultTerms: string[];
|
|
159
|
+
unmatchedTerms: string[];
|
|
160
|
+
truncated?: true;
|
|
161
|
+
connectorScope?: string;
|
|
162
|
+
unknownConnector?: true;
|
|
163
|
+
configuredConnectors?: string[];
|
|
164
|
+
unavailableConnectorCount?: number;
|
|
165
|
+
catalogError?: CatalogFailureDetail;
|
|
166
|
+
guide?: string;
|
|
167
|
+
guideSummary?: string;
|
|
168
|
+
guideRequired?: true;
|
|
169
|
+
guideRequiredReasons?: GuideRequiredReason[];
|
|
170
|
+
guidance?: string;
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
export type CatalogSearchResult = CatalogSearchPage & {
|
|
174
|
+
tools: Array<CatalogSearchTool & {
|
|
175
|
+
connectorTitle?: string;
|
|
176
|
+
guide?: string;
|
|
177
|
+
guideSummary?: string;
|
|
178
|
+
}>;
|
|
179
|
+
};
|
|
180
|
+
export interface CatalogDescription {
|
|
181
|
+
address: string;
|
|
182
|
+
schemaFormat?: "json" | "text";
|
|
183
|
+
name?: string;
|
|
184
|
+
description?: string;
|
|
185
|
+
guide?: string;
|
|
186
|
+
guideSummary?: string;
|
|
187
|
+
guideRequired?: true;
|
|
188
|
+
guideRequiredReasons?: GuideRequiredReason[];
|
|
189
|
+
inputSchema?: unknown;
|
|
190
|
+
outputSchema?: unknown;
|
|
191
|
+
signature?: string;
|
|
192
|
+
outputSchemaSource?: "observed";
|
|
193
|
+
inputSchemaTruncated?: true;
|
|
194
|
+
outputSchemaTruncated?: true;
|
|
195
|
+
annotations?: ToolDef["annotations"];
|
|
196
|
+
error?: string;
|
|
197
|
+
errorDetails?: CatalogDescriptionFailureDetail;
|
|
198
|
+
}
|
|
199
|
+
type CatalogSearchTool = {
|
|
200
|
+
name: string;
|
|
201
|
+
address: string;
|
|
202
|
+
description?: string;
|
|
203
|
+
inputSchema?: unknown;
|
|
204
|
+
outputSchema?: unknown;
|
|
205
|
+
signature?: string;
|
|
206
|
+
schemaFormat?: "json" | "text";
|
|
207
|
+
outputSchemaSource?: "observed";
|
|
208
|
+
inputSchemaTruncated?: true;
|
|
209
|
+
outputSchemaTruncated?: true;
|
|
210
|
+
inputKeys?: string[];
|
|
211
|
+
requiredInputKeys?: string[];
|
|
212
|
+
outputKeys?: string[];
|
|
213
|
+
annotations?: ToolDef["annotations"];
|
|
214
|
+
classification?: ToolDef["classification"];
|
|
215
|
+
guideRequired?: true;
|
|
216
|
+
guideRequiredReasons?: GuideRequiredReason[];
|
|
217
|
+
};
|
|
218
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|