@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
package/dist/errors.js
CHANGED
|
@@ -1,5 +1,64 @@
|
|
|
1
1
|
// Typed failure contract for connector tool calls. Web-API only — no node:
|
|
2
2
|
// imports here.
|
|
3
|
+
import { redactCallArguments } from "./argument-redaction.js";
|
|
4
|
+
const CLASSIFICATION_CODE_TABLE = {
|
|
5
|
+
timeout: true,
|
|
6
|
+
auth_required: true,
|
|
7
|
+
downstream_oauth_required: true,
|
|
8
|
+
oauth_revocation_failed: true,
|
|
9
|
+
provider_permission_denied: true,
|
|
10
|
+
rate_limited: true,
|
|
11
|
+
unavailable: true,
|
|
12
|
+
invalid_args: true,
|
|
13
|
+
not_found: true,
|
|
14
|
+
conflict: true,
|
|
15
|
+
resource_template_ambiguous: true,
|
|
16
|
+
resource_match_budget_exceeded: true,
|
|
17
|
+
input_required_unsupported: true,
|
|
18
|
+
input_required_invalid: true,
|
|
19
|
+
input_required_limit: true,
|
|
20
|
+
connector_call_failed: true,
|
|
21
|
+
executor_overloaded: true,
|
|
22
|
+
executor_cancelled: true,
|
|
23
|
+
executor_closed: true,
|
|
24
|
+
cancelled: true,
|
|
25
|
+
unknown_address: true,
|
|
26
|
+
unknown_tool: true,
|
|
27
|
+
ambiguous_tool_alias: true,
|
|
28
|
+
catalog_lookup_failed: true,
|
|
29
|
+
result_too_large: true,
|
|
30
|
+
destructive_tool_requires_approval: true,
|
|
31
|
+
auth_replay_refused: true,
|
|
32
|
+
write_outcome_unknown: true,
|
|
33
|
+
result_processing_failed: true,
|
|
34
|
+
budget_exceeded: true,
|
|
35
|
+
executor_failed: true,
|
|
36
|
+
program_error: true,
|
|
37
|
+
};
|
|
38
|
+
/** `value` when it is a code connecta assigns, else undefined. */
|
|
39
|
+
export function classificationCode(value) {
|
|
40
|
+
return typeof value === "string" && Object.hasOwn(CLASSIFICATION_CODE_TABLE, value)
|
|
41
|
+
? value
|
|
42
|
+
: undefined;
|
|
43
|
+
}
|
|
44
|
+
/** Drop oversized detail whole; clipping keys or examples changes their meaning. */
|
|
45
|
+
function boundedRepair(details) {
|
|
46
|
+
if (!details)
|
|
47
|
+
return undefined;
|
|
48
|
+
try {
|
|
49
|
+
const text = JSON.stringify(details);
|
|
50
|
+
return new TextEncoder().encode(text).length <= 4096
|
|
51
|
+
? JSON.parse(text)
|
|
52
|
+
: {
|
|
53
|
+
issues: [],
|
|
54
|
+
truncated: true,
|
|
55
|
+
exampleUnavailable: "Repair detail exceeds the response budget. Inspect the published inputSchema.",
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
3
62
|
export const MAX_ARGUMENT_VALIDATION_ISSUES = 3;
|
|
4
63
|
const MAX_ARGUMENT_ISSUE_PATH_CHARS = 256;
|
|
5
64
|
const MAX_ARGUMENT_ISSUE_CODE_CHARS = 64;
|
|
@@ -58,36 +117,40 @@ export function boundedEchoText(value, maxBytes = MAX_ECHOED_BYTES) {
|
|
|
58
117
|
return `${echoDecoder.decode(bytes.slice(0, end))}…`;
|
|
59
118
|
}
|
|
60
119
|
/**
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
* ones — there is nothing honest to put in the field.
|
|
120
|
+
* Snapshot the caller's arguments after bounded schema-aware writeOnly omission,
|
|
121
|
+
* then apply the shared byte budget without clipping. Unresolved sensitivity
|
|
122
|
+
* omits the entire echo. argsRedacted marks partial or withheld arguments as
|
|
123
|
+
* reconciliation context; any retry must use the caller's original arguments.
|
|
66
124
|
*/
|
|
67
|
-
export function echoedCallArgs(args) {
|
|
125
|
+
export function echoedCallArgs(args, schema) {
|
|
68
126
|
if (args === undefined)
|
|
69
127
|
return {};
|
|
70
128
|
let text;
|
|
129
|
+
let redacted = false;
|
|
71
130
|
try {
|
|
72
|
-
|
|
131
|
+
const filtered = schema ? redactCallArguments(args, schema) : { value: args, redacted: false };
|
|
132
|
+
redacted = filtered.redacted;
|
|
133
|
+
if (!("value" in filtered))
|
|
134
|
+
return { argsRedacted: true };
|
|
135
|
+
const safeArgs = filtered.value;
|
|
136
|
+
text = JSON.stringify(safeArgs);
|
|
73
137
|
}
|
|
74
138
|
catch {
|
|
75
|
-
return {};
|
|
139
|
+
return redacted ? { argsRedacted: true } : {};
|
|
76
140
|
}
|
|
77
141
|
if (text === undefined)
|
|
78
142
|
return {};
|
|
79
143
|
return echoEncoder.encode(text).length <= MAX_ECHOED_BYTES
|
|
80
|
-
? { args }
|
|
81
|
-
:
|
|
144
|
+
? { args: JSON.parse(text), ...(redacted ? { argsRedacted: true } : {}) }
|
|
145
|
+
: redacted
|
|
146
|
+
? { argsRedacted: true }
|
|
147
|
+
: {};
|
|
82
148
|
}
|
|
83
149
|
function boundedValidation(details) {
|
|
84
150
|
if (!details)
|
|
85
151
|
return undefined;
|
|
86
|
-
let truncated = details.truncated === true ||
|
|
87
|
-
|
|
88
|
-
const issues = details.issues
|
|
89
|
-
.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES)
|
|
90
|
-
.map((issue) => {
|
|
152
|
+
let truncated = details.truncated === true || details.issues.length > MAX_ARGUMENT_VALIDATION_ISSUES;
|
|
153
|
+
const issues = details.issues.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES).map((issue) => {
|
|
91
154
|
const path = boundedIssueText(issue.path, MAX_ARGUMENT_ISSUE_PATH_CHARS);
|
|
92
155
|
const code = boundedIssueText(issue.code, MAX_ARGUMENT_ISSUE_CODE_CHARS);
|
|
93
156
|
const expected = boundedIssueText(issue.expected, MAX_ARGUMENT_ISSUE_EXPECTED_CHARS);
|
|
@@ -103,17 +166,30 @@ function boundedValidation(details) {
|
|
|
103
166
|
...(truncated ? { truncated: true } : {}),
|
|
104
167
|
};
|
|
105
168
|
}
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
"
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
169
|
+
/** The network errnos `networkErrorCode` reports, and `timeout`. */
|
|
170
|
+
export const NETWORK_ERROR_CODES = new Set([
|
|
171
|
+
"ECONNREFUSED",
|
|
172
|
+
"ENOTFOUND",
|
|
173
|
+
"ECONNRESET",
|
|
174
|
+
"ETIMEDOUT",
|
|
175
|
+
"EAI_AGAIN",
|
|
176
|
+
"EAI_FAIL",
|
|
177
|
+
"EHOSTUNREACH",
|
|
178
|
+
"ENETUNREACH",
|
|
179
|
+
"ENETDOWN",
|
|
180
|
+
"EHOSTDOWN",
|
|
181
|
+
"ECONNABORTED",
|
|
182
|
+
"EPIPE",
|
|
183
|
+
"EACCES",
|
|
184
|
+
"EPERM",
|
|
185
|
+
"UND_ERR_CONNECT_TIMEOUT",
|
|
186
|
+
"UND_ERR_HEADERS_TIMEOUT",
|
|
187
|
+
"UND_ERR_BODY_TIMEOUT",
|
|
188
|
+
"UND_ERR_SOCKET",
|
|
189
|
+
"timeout",
|
|
112
190
|
]);
|
|
113
191
|
function networkCode(value) {
|
|
114
|
-
return typeof value === "string" && value.length <= 32 && NETWORK_ERROR_CODES.has(value)
|
|
115
|
-
? value
|
|
116
|
-
: undefined;
|
|
192
|
+
return typeof value === "string" && value.length <= 32 && NETWORK_ERROR_CODES.has(value) ? value : undefined;
|
|
117
193
|
}
|
|
118
194
|
function sanitizedUnavailableDetails(details) {
|
|
119
195
|
if (!details)
|
|
@@ -122,8 +198,7 @@ function sanitizedUnavailableDetails(details) {
|
|
|
122
198
|
if (typeof details.host === "string") {
|
|
123
199
|
try {
|
|
124
200
|
const url = new URL(details.host);
|
|
125
|
-
if ((url.protocol === "https:" || url.protocol === "http:") &&
|
|
126
|
-
echoEncoder.encode(url.origin).length <= 253)
|
|
201
|
+
if ((url.protocol === "https:" || url.protocol === "http:") && echoEncoder.encode(url.origin).length <= 253)
|
|
127
202
|
host = url.origin;
|
|
128
203
|
}
|
|
129
204
|
catch {
|
|
@@ -137,33 +212,73 @@ function sanitizedUnavailableDetails(details) {
|
|
|
137
212
|
export function networkErrorCode(error) {
|
|
138
213
|
if (!error || typeof error !== "object")
|
|
139
214
|
return undefined;
|
|
140
|
-
if (error instanceof Error &&
|
|
141
|
-
(error.name === "AbortError" || error.name === "TimeoutError")) {
|
|
215
|
+
if (error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError")) {
|
|
142
216
|
return "timeout";
|
|
143
217
|
}
|
|
144
218
|
const runtime = error;
|
|
145
219
|
const cause = runtime.cause;
|
|
146
|
-
return networkCode(runtime.code) ??
|
|
147
|
-
? networkCode(cause.code)
|
|
148
|
-
: undefined);
|
|
220
|
+
return (networkCode(runtime.code) ??
|
|
221
|
+
(cause && typeof cause === "object" ? networkCode(cause.code) : undefined));
|
|
149
222
|
}
|
|
150
|
-
/**
|
|
151
|
-
|
|
152
|
-
|
|
223
|
+
/**
|
|
224
|
+
* Use at a fetch boundary where the destination and transport failure are
|
|
225
|
+
* known. The runtime's error is read for its errno and dropped, never kept as
|
|
226
|
+
* `cause`: its message and cause chain can quote the URL, headers, or body of
|
|
227
|
+
* the request that failed, and a logger that renders an error renders its
|
|
228
|
+
* cause. The origin and errno in `details` are what survives.
|
|
229
|
+
*
|
|
230
|
+
* The one failure kept is the request's own abort reason, when that is what
|
|
231
|
+
* the fetch rejected with: the caller wrote it, not the downstream, and it is
|
|
232
|
+
* how a cancelled request tells its reason from a network failure.
|
|
233
|
+
*/
|
|
234
|
+
export function unavailableCallError(failure, host, message = "Could not reach the downstream service.", signal) {
|
|
235
|
+
const code = networkErrorCode(failure);
|
|
236
|
+
const ownReason = signal?.aborted === true && failure === signal.reason;
|
|
153
237
|
return new ConnectorCallError("unavailable", message, {
|
|
154
|
-
cause,
|
|
238
|
+
...(ownReason ? { cause: failure } : {}),
|
|
155
239
|
details: { ...(host ? { host } : {}), ...(code ? { code } : {}) },
|
|
156
240
|
});
|
|
157
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* A failure told in connecta's words because the original's text came from a
|
|
244
|
+
* downstream or authorization server, which can echo what the request carried
|
|
245
|
+
* or plant whatever it likes. There is no `cause`: the original is dropped
|
|
246
|
+
* whole, never masked.
|
|
247
|
+
*
|
|
248
|
+
* It is classified exactly as the original would have been. That verdict is
|
|
249
|
+
* read from the original once, here, and kept as two flags, so withholding
|
|
250
|
+
* the text moves no failure between `timeout`, retryable, and the caller's
|
|
251
|
+
* fallback code. Never wrap a `ConnectorCallError`: it already speaks in
|
|
252
|
+
* connecta's words and carries its own code.
|
|
253
|
+
*/
|
|
254
|
+
export class WithheldTextError extends Error {
|
|
255
|
+
/** The original read as a timeout. */
|
|
256
|
+
timeout;
|
|
257
|
+
retryable;
|
|
258
|
+
constructor(message, original) {
|
|
259
|
+
super(message);
|
|
260
|
+
this.name = "WithheldTextError";
|
|
261
|
+
const verdict = classifyCallError(original);
|
|
262
|
+
this.timeout = verdict.code === "timeout";
|
|
263
|
+
this.retryable = verdict.retryable;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
158
266
|
const RETRYABLE_BY_CODE = {
|
|
159
267
|
timeout: true,
|
|
160
268
|
rate_limited: true,
|
|
161
269
|
unavailable: true,
|
|
162
270
|
auth_required: false,
|
|
271
|
+
downstream_oauth_required: false,
|
|
272
|
+
oauth_revocation_failed: false,
|
|
273
|
+
provider_permission_denied: false,
|
|
163
274
|
invalid_args: false,
|
|
164
275
|
not_found: false,
|
|
165
276
|
conflict: false,
|
|
277
|
+
resource_template_ambiguous: false,
|
|
278
|
+
resource_match_budget_exceeded: false,
|
|
166
279
|
input_required_unsupported: false,
|
|
280
|
+
input_required_invalid: false,
|
|
281
|
+
input_required_limit: false,
|
|
167
282
|
connector_call_failed: false,
|
|
168
283
|
};
|
|
169
284
|
/** Entries a conflict's `current` map may carry. */
|
|
@@ -196,9 +311,9 @@ function normalizeRetryAfterMs(value) {
|
|
|
196
311
|
}
|
|
197
312
|
/**
|
|
198
313
|
* Throw from `Connector.callTool` (or anything beneath it) to classify a
|
|
199
|
-
* failure exactly. Untyped errors
|
|
200
|
-
*
|
|
201
|
-
*
|
|
314
|
+
* failure exactly. Untyped errors are non-retryable unless a runtime errno
|
|
315
|
+
* or abort identifies a transport failure. This class supplies the connector's
|
|
316
|
+
* reviewed verdict. `retryable` defaults per
|
|
202
317
|
* code (timeout, rate_limited, and unavailable retry; the rest do not) and may
|
|
203
318
|
* be overridden.
|
|
204
319
|
*
|
|
@@ -220,6 +335,7 @@ export class ConnectorCallError extends Error {
|
|
|
220
335
|
retryAfterMs;
|
|
221
336
|
/** Bounded schema findings for `invalid_args`; never submitted values. */
|
|
222
337
|
validation;
|
|
338
|
+
repair;
|
|
223
339
|
/** Sanitized transport diagnostics for `unavailable` only. */
|
|
224
340
|
details;
|
|
225
341
|
/**
|
|
@@ -233,79 +349,51 @@ export class ConnectorCallError extends Error {
|
|
|
233
349
|
this.code = code;
|
|
234
350
|
this.retryable = opts.retryable ?? RETRYABLE_BY_CODE[code];
|
|
235
351
|
this.retryAfterMs = normalizeRetryAfterMs(opts.retryAfterMs);
|
|
236
|
-
this.details =
|
|
237
|
-
|
|
238
|
-
this.
|
|
239
|
-
code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
|
|
352
|
+
this.details = code === "unavailable" ? sanitizedUnavailableDetails(opts.details) : undefined;
|
|
353
|
+
this.validation = code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
|
|
354
|
+
this.repair = code === "invalid_args" ? boundedRepair(opts.repair) : undefined;
|
|
240
355
|
this.current = code === "conflict" ? boundedCurrent(opts.current) : undefined;
|
|
241
356
|
}
|
|
242
357
|
}
|
|
243
|
-
/**
|
|
244
|
-
* Codes whose retryability is a fact about connecta's own framing, never a
|
|
245
|
-
* guess from text. The message embeds the address the caller asked for, so a
|
|
246
|
-
* connector named `svc-503` or `temporary-export` would otherwise flip a policy
|
|
247
|
-
* refusal into `retryable: true` through the heuristic below — and a caller that
|
|
248
|
-
* trusts the flag would cheerfully retry a refusal forever.
|
|
249
|
-
*/
|
|
250
|
-
const NEVER_RETRYABLE_FRAMING = new Set([
|
|
251
|
-
"result_processing_failed",
|
|
252
|
-
"unknown_address",
|
|
253
|
-
"unknown_tool",
|
|
254
|
-
"ambiguous_tool_alias",
|
|
255
|
-
"destructive_tool_requires_approval",
|
|
256
|
-
]);
|
|
257
|
-
/**
|
|
258
|
-
* Details for a failure connecta itself framed — an address it could not
|
|
259
|
-
* resolve, a tool it refuses to run — rather than one a connector threw.
|
|
260
|
-
*/
|
|
358
|
+
/** Retryability of connecta framing depends only on its code. */
|
|
261
359
|
export function framingError(code, message) {
|
|
262
360
|
return {
|
|
263
361
|
code,
|
|
264
362
|
message,
|
|
265
|
-
retryable:
|
|
266
|
-
? false
|
|
267
|
-
: messageLooksRetryable(message),
|
|
363
|
+
retryable: code === "timeout" || code === "unavailable" || code === "rate_limited",
|
|
268
364
|
};
|
|
269
365
|
}
|
|
270
|
-
|
|
271
|
-
const TIMEOUT_MESSAGE_RE = /timed out|timeout/i;
|
|
272
|
-
/** Message-text fallback used when an error carries no typed classification. */
|
|
273
|
-
function messageLooksRetryable(message) {
|
|
274
|
-
return RETRYABLE_MESSAGE_RE.test(message);
|
|
275
|
-
}
|
|
276
|
-
/**
|
|
277
|
-
* Classify a value thrown by a connector call. A `ConnectorCallError` is
|
|
278
|
-
* authoritative; anything else falls back to the historical message-text
|
|
279
|
-
* heuristic.
|
|
280
|
-
*/
|
|
366
|
+
/** Typed connector verdicts and runtime facts only. Prose never changes a verdict. */
|
|
281
367
|
export function classifyCallError(err, fallbackCode = "connector_call_failed") {
|
|
282
368
|
if (err instanceof ConnectorCallError) {
|
|
283
369
|
return {
|
|
284
370
|
code: err.code,
|
|
285
371
|
message: err.message,
|
|
286
372
|
retryable: err.retryable,
|
|
287
|
-
...(err.retryAfterMs !== undefined
|
|
288
|
-
? { retryAfterMs: err.retryAfterMs }
|
|
289
|
-
: {}),
|
|
373
|
+
...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
|
|
290
374
|
...(err.validation ? { validation: err.validation } : {}),
|
|
375
|
+
...(err.repair ? { repair: err.repair } : {}),
|
|
291
376
|
...(err.details ? { details: err.details } : {}),
|
|
292
377
|
...(err.current ? { current: err.current } : {}),
|
|
293
378
|
};
|
|
294
379
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (err instanceof Error && err.name === "AbortError") {
|
|
302
|
-
return { code: "timeout", message: err.message, retryable: true };
|
|
380
|
+
if (err instanceof WithheldTextError) {
|
|
381
|
+
return {
|
|
382
|
+
code: err.timeout ? "timeout" : fallbackCode,
|
|
383
|
+
message: err.message,
|
|
384
|
+
retryable: err.retryable,
|
|
385
|
+
};
|
|
303
386
|
}
|
|
304
387
|
const message = err instanceof Error ? err.message : String(err);
|
|
388
|
+
const network = networkErrorCode(err);
|
|
305
389
|
return {
|
|
306
|
-
code:
|
|
390
|
+
code: network === "timeout" || network === "ETIMEDOUT" || network?.endsWith("_TIMEOUT")
|
|
391
|
+
? "timeout"
|
|
392
|
+
: network
|
|
393
|
+
? "unavailable"
|
|
394
|
+
: fallbackCode,
|
|
307
395
|
message,
|
|
308
|
-
retryable:
|
|
396
|
+
retryable: network !== undefined,
|
|
309
397
|
};
|
|
310
398
|
}
|
|
311
399
|
export function msg(err) {
|