@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.
Files changed (319) hide show
  1. package/CHANGELOG.md +788 -5
  2. package/README.md +62 -42
  3. package/bin/connecta.mjs +110 -139
  4. package/bin/meta-tool-names.d.mts +2 -0
  5. package/bin/meta-tool-names.mjs +9 -0
  6. package/bin/version.mjs +3 -0
  7. package/dist/access-tokens.js +53 -63
  8. package/dist/activity-request.js +8 -0
  9. package/dist/activity.d.ts +76 -42
  10. package/dist/activity.js +110 -42
  11. package/dist/auth/clerk-sdk/client.d.ts +65 -0
  12. package/dist/auth/clerk-sdk/client.js +5 -0
  13. package/dist/auth/clerk-sdk/generated.js +1845 -0
  14. package/dist/auth/clerk-transport.js +19 -0
  15. package/dist/auth/clerk.d.ts +17 -7
  16. package/dist/auth/clerk.js +189 -107
  17. package/dist/auth/cloudflare-access.js +25 -26
  18. package/dist/auth/downstream-client-metadata.d.ts +29 -0
  19. package/dist/auth/downstream-client-metadata.js +133 -0
  20. package/dist/auth/downstream-oauth.js +1584 -1580
  21. package/dist/auth/downstream-revocation.js +106 -0
  22. package/dist/auth/oauth-token-response.js +231 -0
  23. package/dist/auth/oauth-v2-migration.js +116 -0
  24. package/dist/auth/static-oauth.js +93 -71
  25. package/dist/auth-elicitation.js +283 -0
  26. package/dist/branding.d.ts +8 -16
  27. package/dist/branding.js +26 -59
  28. package/dist/byte-read-response.js +39 -0
  29. package/dist/call-admission.js +12 -16
  30. package/dist/catalog-cache.js +739 -0
  31. package/dist/catalog-drift.d.ts +50 -15
  32. package/dist/catalog-drift.js +365 -128
  33. package/dist/catalog-fingerprint.js +2 -4
  34. package/dist/catalog-freshness.js +13 -0
  35. package/dist/catalog-limits.js +2 -2
  36. package/dist/catalog-service.js +368 -224
  37. package/dist/catalog.js +43 -84
  38. package/dist/concurrency.js +3 -4
  39. package/dist/config-defaults.d.ts +39 -0
  40. package/dist/config-defaults.js +46 -0
  41. package/dist/config-schema.d.ts +181 -0
  42. package/dist/config-schema.js +435 -0
  43. package/dist/config-value-sources.js +102 -0
  44. package/dist/config.d.ts +631 -0
  45. package/dist/config.js +503 -0
  46. package/dist/connector-access.d.ts +1 -0
  47. package/dist/connector-access.js +13 -15
  48. package/dist/connector-caller.d.ts +8 -0
  49. package/dist/connector-caller.js +15 -6
  50. package/dist/connector-scope.js +1 -1
  51. package/dist/connectors/api-connector.d.ts +59 -7
  52. package/dist/connectors/api-connector.js +106 -19
  53. package/dist/connectors/api.js +4 -1
  54. package/dist/connectors/guarded-fetch.d.ts +144 -0
  55. package/dist/connectors/guarded-fetch.js +84 -35
  56. package/dist/connectors/negotiation-cache.js +46 -0
  57. package/dist/connectors/option-shapes.js +27 -0
  58. package/dist/connectors/remote-mcp.d.ts +30 -4
  59. package/dist/connectors/remote-mcp.js +1774 -320
  60. package/dist/connectors/resource-uri.js +335 -0
  61. package/dist/credential-contract.d.ts +10 -0
  62. package/dist/credential-rules.js +1 -3
  63. package/dist/credential-url.js +108 -0
  64. package/dist/credentials.d.ts +6 -1
  65. package/dist/credentials.js +27 -18
  66. package/dist/d1.d.ts +130 -0
  67. package/dist/d1.js +290 -0
  68. package/dist/describe-config.d.ts +165 -0
  69. package/dist/describe-config.js +315 -0
  70. package/dist/described.js +106 -0
  71. package/dist/downstream-input-context.js +119 -0
  72. package/dist/downstream-input.js +323 -0
  73. package/dist/errors.d.ts +97 -20
  74. package/dist/errors.js +158 -80
  75. package/dist/execute.js +453 -305
  76. package/dist/executor-admission.d.ts +1 -0
  77. package/dist/executor-admission.js +11 -15
  78. package/dist/executor-contract.d.ts +20 -0
  79. package/dist/executor-contract.js +48 -0
  80. package/dist/executor-result.js +24 -9
  81. package/dist/executors/quickjs-child.js +3 -4
  82. package/dist/executors/quickjs-runtime.js +147 -59
  83. package/dist/executors/quickjs.js +29 -35
  84. package/dist/favicon.js +1 -2
  85. package/dist/fix-prompt.js +1 -3
  86. package/dist/guest-runtime.js +188 -0
  87. package/dist/guest-types.d.ts +176 -0
  88. package/dist/guest-types.js +1 -0
  89. package/dist/html-security.js +24 -0
  90. package/dist/identity.js +1 -3
  91. package/dist/inbound-credential.js +52 -0
  92. package/dist/index.d.ts +24 -256
  93. package/dist/index.js +65 -478
  94. package/dist/invocation-auth.js +69 -0
  95. package/dist/invocation.js +230 -73
  96. package/dist/json-schema.d.ts +1 -1
  97. package/dist/mcp-client-context.js +35 -0
  98. package/dist/mcp-result.js +11 -7
  99. package/dist/meta-output.js +76 -0
  100. package/dist/meta-tool-names.d.ts +2 -0
  101. package/dist/meta-tool-names.js +3 -0
  102. package/dist/meta-tools.js +285 -209
  103. package/dist/module-contracts.d.ts +8 -23
  104. package/dist/node.d.ts +0 -2
  105. package/dist/node.js +2 -2
  106. package/dist/oauth-callback-outcome.js +1 -3
  107. package/dist/oauth-handoff.js +117 -0
  108. package/dist/oauth-sealing.js +20 -0
  109. package/dist/operator-record.d.ts +137 -0
  110. package/dist/operator-record.js +420 -0
  111. package/dist/operator-ui/assets.js +31 -0
  112. package/dist/operator-ui/contract.d.ts +72 -0
  113. package/dist/operator-ui/contract.js +1 -0
  114. package/dist/operator-ui/fix-prompts.d.ts +18 -0
  115. package/dist/operator-ui/generated.js +5 -4
  116. package/dist/operator-ui/model.d.ts +12 -87
  117. package/dist/operator-ui/model.js +2 -9
  118. package/dist/operator-ui/setup-commands.js +1 -3
  119. package/dist/operator-ui/view.d.ts +323 -0
  120. package/dist/operator-ui/view.js +62 -189
  121. package/dist/page-styles.js +2 -3
  122. package/dist/program-source.js +14 -2
  123. package/dist/{exempt-writes.js → program-writes.js} +55 -18
  124. package/dist/provider.d.ts +142 -0
  125. package/dist/provider.js +187 -0
  126. package/dist/providers/_shared/google/result-size.js +57 -0
  127. package/dist/providers/_shared/google/service-account.d.ts +58 -0
  128. package/dist/providers/_shared/google/service-account.js +500 -0
  129. package/dist/providers/_shared/google/workspace.d.ts +276 -0
  130. package/dist/providers/_shared/google/workspace.js +518 -0
  131. package/dist/providers/{basecamp.d.ts → basecamp/index.d.ts} +6 -28
  132. package/dist/providers/basecamp/index.js +997 -0
  133. package/dist/providers/basecamp/skill.generated.js +9 -0
  134. package/dist/providers/{breeze.d.ts → breeze/index.d.ts} +2 -2
  135. package/dist/providers/{breeze.js → breeze/index.js} +184 -140
  136. package/dist/providers/breeze/skill.generated.js +9 -0
  137. package/dist/providers/{ccb.d.ts → ccb/index.d.ts} +2 -2
  138. package/dist/providers/{ccb.js → ccb/index.js} +271 -116
  139. package/dist/providers/ccb/skill.generated.js +9 -0
  140. package/dist/providers/{cloudflare.d.ts → cloudflare/index.d.ts} +8 -7
  141. package/dist/providers/{cloudflare.js → cloudflare/index.js} +171 -738
  142. package/dist/providers/cloudflare/skill.generated.js +10 -0
  143. package/dist/providers/docs/index.d.ts +54 -0
  144. package/dist/providers/docs/index.js +1237 -0
  145. package/dist/providers/docs/skill.generated.js +9 -0
  146. package/dist/providers/drive/index.d.ts +53 -0
  147. package/dist/providers/drive/index.js +1523 -0
  148. package/dist/providers/drive/skill.generated.js +9 -0
  149. package/dist/providers/forms/index.d.ts +54 -0
  150. package/dist/providers/forms/index.js +1217 -0
  151. package/dist/providers/forms/skill.generated.js +11 -0
  152. package/dist/providers/github/auth.d.ts +32 -0
  153. package/dist/providers/github/auth.js +361 -0
  154. package/dist/providers/github/hosted.js +218 -0
  155. package/dist/providers/github/index.d.ts +13 -0
  156. package/dist/providers/github/index.js +140 -0
  157. package/dist/providers/github/key.js +100 -0
  158. package/dist/providers/github/rest.js +321 -0
  159. package/dist/providers/github/scope.d.ts +29 -0
  160. package/dist/providers/github/scope.js +124 -0
  161. package/dist/providers/github/skill.generated.js +8 -0
  162. package/dist/providers/gmail/index.d.ts +51 -0
  163. package/dist/providers/gmail/index.js +1436 -0
  164. package/dist/providers/gmail/skill.generated.js +9 -0
  165. package/dist/providers/{linear.d.ts → linear/index.d.ts} +11 -14
  166. package/dist/providers/linear/index.js +352 -0
  167. package/dist/providers/linear/skill.generated.js +8 -0
  168. package/dist/providers/{mixpanel.d.ts → mixpanel/index.d.ts} +5 -10
  169. package/dist/providers/mixpanel/index.js +416 -0
  170. package/dist/providers/mixpanel/skill.generated.js +9 -0
  171. package/dist/providers/{notion.d.ts → notion/index.d.ts} +8 -8
  172. package/dist/providers/{notion.js → notion/index.js} +226 -239
  173. package/dist/providers/notion/skill.generated.js +10 -0
  174. package/dist/providers/{overflow.d.ts → overflow/index.d.ts} +2 -2
  175. package/dist/providers/{overflow.js → overflow/index.js} +74 -111
  176. package/dist/providers/overflow/skill.generated.js +8 -0
  177. package/dist/providers/{planning-center.d.ts → planning-center/index.d.ts} +2 -2
  178. package/dist/providers/{planning-center.js → planning-center/index.js} +264 -104
  179. package/dist/providers/planning-center/skill.generated.js +10 -0
  180. package/dist/providers/{revenuecat.d.ts → revenuecat/index.d.ts} +5 -10
  181. package/dist/providers/revenuecat/index.js +557 -0
  182. package/dist/providers/revenuecat/skill.generated.js +11 -0
  183. package/dist/providers/sheets/index.d.ts +54 -0
  184. package/dist/providers/sheets/index.js +1237 -0
  185. package/dist/providers/sheets/skill.generated.js +10 -0
  186. package/dist/providers/slides/index.d.ts +53 -0
  187. package/dist/providers/slides/index.js +2645 -0
  188. package/dist/providers/slides/skill.generated.js +9 -0
  189. package/dist/providers/{stripe.d.ts → stripe/index.d.ts} +5 -12
  190. package/dist/providers/stripe/index.js +266 -0
  191. package/dist/providers/stripe/skill.generated.js +11 -0
  192. package/dist/providers/{tithely.d.ts → tithely/index.d.ts} +2 -2
  193. package/dist/providers/{tithely.js → tithely/index.js} +60 -91
  194. package/dist/providers/tithely/skill.generated.js +8 -0
  195. package/dist/providers/{vercel.d.ts → vercel/index.d.ts} +8 -8
  196. package/dist/providers/vercel/index.js +1038 -0
  197. package/dist/providers/vercel/mcp-ownership.js +212 -0
  198. package/dist/providers/vercel/skill.generated.js +11 -0
  199. package/dist/registry.d.ts +108 -171
  200. package/dist/registry.js +513 -925
  201. package/dist/request-state.js +21 -0
  202. package/dist/resource-read.js +100 -0
  203. package/dist/result-shapes.js +17 -49
  204. package/dist/retired-toolkits.js +1 -1
  205. package/dist/routes/access-tokens.js +3 -6
  206. package/dist/routes/activity-context.js +21 -0
  207. package/dist/routes/activity-disclosure.js +40 -0
  208. package/dist/routes/activity.js +59 -21
  209. package/dist/routes/actor-labels.js +3 -50
  210. package/dist/routes/connect.js +221 -0
  211. package/dist/routes/credentials.js +15 -27
  212. package/dist/routes/mcp.js +356 -130
  213. package/dist/routes/oauth-client-metadata.js +15 -0
  214. package/dist/routes/oauth-management.js +45 -107
  215. package/dist/routes/oauth.js +110 -57
  216. package/dist/routes/operator.js +3 -3
  217. package/dist/routes/shared.d.ts +25 -64
  218. package/dist/routes/shared.js +160 -80
  219. package/dist/routes/skills.js +30 -0
  220. package/dist/routes/ui-config.js +225 -0
  221. package/dist/routes/ui-data.js +40 -35
  222. package/dist/routes/ui.js +66 -56
  223. package/dist/runtime/admission.js +4 -2
  224. package/dist/runtime/call-admission.js +3 -1
  225. package/dist/runtime/connector-scope.js +1 -4
  226. package/dist/runtime/run.js +10 -39
  227. package/dist/runtime/services.js +12 -117
  228. package/dist/runtime/shared-read.js +1 -3
  229. package/dist/runtime/storage.js +8 -1
  230. package/dist/sent-secrets.d.ts +52 -0
  231. package/dist/sent-secrets.js +474 -0
  232. package/dist/server.js +28 -71
  233. package/dist/skills.js +406 -174
  234. package/dist/sqlite.d.ts +48 -0
  235. package/dist/sqlite.js +166 -0
  236. package/dist/storage/keys.js +428 -0
  237. package/dist/storage/memory.js +7 -0
  238. package/dist/storage/sql.d.ts +66 -0
  239. package/dist/storage/sql.js +534 -0
  240. package/dist/timeout.js +4 -2
  241. package/dist/tool-name.js +17 -0
  242. package/dist/tool-safety.d.ts +9 -35
  243. package/dist/tool-safety.js +20 -40
  244. package/dist/types.d.ts +320 -54
  245. package/dist/types.js +0 -1
  246. package/dist/ui.d.ts +7 -19
  247. package/dist/ui.js +76 -90
  248. package/dist/url-safety.js +3 -6
  249. package/dist/usage-guide.js +137 -0
  250. package/dist/validate.d.ts +7 -0
  251. package/dist/validate.js +309 -47
  252. package/dist/version.d.ts +1 -7
  253. package/dist/version.js +3 -7
  254. package/dist/worker.d.ts +11 -0
  255. package/dist/worker.js +434 -0
  256. package/documentation/architecture.md +664 -231
  257. package/documentation/auth.md +936 -546
  258. package/documentation/code-mode.md +501 -312
  259. package/documentation/meta-tools.md +449 -200
  260. package/documentation/operator-tests.md +93 -0
  261. package/documentation/provider-migration-0.29.md +60 -0
  262. package/examples/worker/AGENTS.md +34 -12
  263. package/examples/worker/README.md +286 -255
  264. package/examples/worker/kv-to-d1.wrangler.jsonc +26 -0
  265. package/examples/worker/scripts/copy-kv-to-d1.mjs +162 -0
  266. package/examples/worker/src/connecta.config.ts +151 -0
  267. package/examples/worker/src/index.ts +14 -197
  268. package/examples/worker/wrangler.jsonc +15 -35
  269. package/package.json +120 -54
  270. package/templates/node/.dockerignore +1 -2
  271. package/templates/node/.env.example +20 -21
  272. package/templates/node/AGENTS.md +21 -17
  273. package/templates/node/Dockerfile +3 -5
  274. package/templates/node/README.md +133 -58
  275. package/templates/node/docker-compose.yml +11 -12
  276. package/templates/node/package.json +4 -2
  277. package/templates/node/src/connecta.config.ts +119 -0
  278. package/templates/node/src/index.ts +9 -154
  279. package/templates/node/src/provision-token.ts +17 -0
  280. package/AGENTS.md +0 -170
  281. package/dist/artifacts/connector.d.ts +0 -58
  282. package/dist/artifacts/connector.js +0 -730
  283. package/dist/artifacts/document.js +0 -86
  284. package/dist/artifacts/guide.js +0 -140
  285. package/dist/artifacts/html-scan.js +0 -329
  286. package/dist/artifacts/json.js +0 -78
  287. package/dist/artifacts/kv-store.d.ts +0 -20
  288. package/dist/artifacts/kv-store.js +0 -140
  289. package/dist/artifacts/markdown.js +0 -478
  290. package/dist/artifacts/module.d.ts +0 -37
  291. package/dist/artifacts/module.js +0 -66
  292. package/dist/artifacts/operations.d.ts +0 -197
  293. package/dist/artifacts/operations.js +0 -1002
  294. package/dist/artifacts/refresh.d.ts +0 -55
  295. package/dist/artifacts/refresh.js +0 -236
  296. package/dist/artifacts/routes.js +0 -206
  297. package/dist/artifacts/types.d.ts +0 -214
  298. package/dist/artifacts/types.js +0 -22
  299. package/dist/artifacts/validate.d.ts +0 -62
  300. package/dist/artifacts/validate.js +0 -651
  301. package/dist/artifacts.d.ts +0 -6
  302. package/dist/artifacts.js +0 -9
  303. package/dist/auth/bearer.d.ts +0 -11
  304. package/dist/auth/bearer.js +0 -50
  305. package/dist/providers/basecamp.js +0 -445
  306. package/dist/providers/linear.js +0 -217
  307. package/dist/providers/mixpanel.js +0 -247
  308. package/dist/providers/revenuecat.js +0 -317
  309. package/dist/providers/stripe.js +0 -253
  310. package/dist/providers/vercel.js +0 -1253
  311. package/dist/storage/file.d.ts +0 -15
  312. package/dist/storage/file.js +0 -455
  313. package/ethos.md +0 -93
  314. package/examples/worker/src/cloudflare-kv.ts +0 -43
  315. package/examples/worker/src/d1-activity-row.ts +0 -155
  316. package/examples/worker/src/d1-activity.ts +0 -147
  317. package/examples/worker/src/d1-storage.ts +0 -138
  318. package/examples/worker/src/r2-artifact-blobs.ts +0 -29
  319. package/templates/node/src/file-activity.ts +0 -182
package/dist/errors.js CHANGED
@@ -1,5 +1,63 @@
1
1
  // Typed failure contract for connector tool calls. Web-API only — no node:
2
2
  // imports here.
3
+ const CLASSIFICATION_CODE_TABLE = {
4
+ timeout: true,
5
+ auth_required: true,
6
+ downstream_oauth_required: true,
7
+ oauth_revocation_failed: true,
8
+ provider_permission_denied: true,
9
+ rate_limited: true,
10
+ unavailable: true,
11
+ invalid_args: true,
12
+ not_found: true,
13
+ conflict: true,
14
+ resource_template_ambiguous: true,
15
+ resource_match_budget_exceeded: true,
16
+ input_required_unsupported: true,
17
+ input_required_invalid: true,
18
+ input_required_limit: true,
19
+ connector_call_failed: true,
20
+ executor_overloaded: true,
21
+ executor_cancelled: true,
22
+ executor_closed: true,
23
+ cancelled: true,
24
+ unknown_address: true,
25
+ unknown_tool: true,
26
+ ambiguous_tool_alias: true,
27
+ catalog_lookup_failed: true,
28
+ result_too_large: true,
29
+ destructive_tool_requires_approval: true,
30
+ auth_replay_refused: true,
31
+ write_outcome_unknown: true,
32
+ result_processing_failed: true,
33
+ budget_exceeded: true,
34
+ executor_failed: true,
35
+ program_error: true,
36
+ };
37
+ /** `value` when it is a code connecta assigns, else undefined. */
38
+ export function classificationCode(value) {
39
+ return typeof value === "string" && Object.hasOwn(CLASSIFICATION_CODE_TABLE, value)
40
+ ? value
41
+ : undefined;
42
+ }
43
+ /** Drop oversized detail whole; clipping keys or examples changes their meaning. */
44
+ function boundedRepair(details) {
45
+ if (!details)
46
+ return undefined;
47
+ try {
48
+ const text = JSON.stringify(details);
49
+ return new TextEncoder().encode(text).length <= 4096
50
+ ? JSON.parse(text)
51
+ : {
52
+ issues: [],
53
+ truncated: true,
54
+ exampleUnavailable: "Repair detail exceeds the response budget. Inspect the published inputSchema.",
55
+ };
56
+ }
57
+ catch {
58
+ return undefined;
59
+ }
60
+ }
3
61
  export const MAX_ARGUMENT_VALIDATION_ISSUES = 3;
4
62
  const MAX_ARGUMENT_ISSUE_PATH_CHARS = 256;
5
63
  const MAX_ARGUMENT_ISSUE_CODE_CHARS = 64;
@@ -76,18 +134,13 @@ export function echoedCallArgs(args) {
76
134
  }
77
135
  if (text === undefined)
78
136
  return {};
79
- return echoEncoder.encode(text).length <= MAX_ECHOED_BYTES
80
- ? { args }
81
- : {};
137
+ return echoEncoder.encode(text).length <= MAX_ECHOED_BYTES ? { args: JSON.parse(text) } : {};
82
138
  }
83
139
  function boundedValidation(details) {
84
140
  if (!details)
85
141
  return undefined;
86
- let truncated = details.truncated === true ||
87
- details.issues.length > MAX_ARGUMENT_VALIDATION_ISSUES;
88
- const issues = details.issues
89
- .slice(0, MAX_ARGUMENT_VALIDATION_ISSUES)
90
- .map((issue) => {
142
+ let truncated = details.truncated === true || details.issues.length > MAX_ARGUMENT_VALIDATION_ISSUES;
143
+ const issues = details.issues.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES).map((issue) => {
91
144
  const path = boundedIssueText(issue.path, MAX_ARGUMENT_ISSUE_PATH_CHARS);
92
145
  const code = boundedIssueText(issue.code, MAX_ARGUMENT_ISSUE_CODE_CHARS);
93
146
  const expected = boundedIssueText(issue.expected, MAX_ARGUMENT_ISSUE_EXPECTED_CHARS);
@@ -103,17 +156,30 @@ function boundedValidation(details) {
103
156
  ...(truncated ? { truncated: true } : {}),
104
157
  };
105
158
  }
106
- const NETWORK_ERROR_CODES = new Set([
107
- "ECONNREFUSED", "ENOTFOUND", "ECONNRESET", "ETIMEDOUT", "EAI_AGAIN",
108
- "EAI_FAIL", "EHOSTUNREACH", "ENETUNREACH", "ENETDOWN", "EHOSTDOWN",
109
- "ECONNABORTED", "EPIPE", "EACCES", "EPERM",
110
- "UND_ERR_CONNECT_TIMEOUT", "UND_ERR_HEADERS_TIMEOUT", "UND_ERR_BODY_TIMEOUT",
111
- "UND_ERR_SOCKET", "timeout",
159
+ /** The network errnos `networkErrorCode` reports, and `timeout`. */
160
+ export const NETWORK_ERROR_CODES = new Set([
161
+ "ECONNREFUSED",
162
+ "ENOTFOUND",
163
+ "ECONNRESET",
164
+ "ETIMEDOUT",
165
+ "EAI_AGAIN",
166
+ "EAI_FAIL",
167
+ "EHOSTUNREACH",
168
+ "ENETUNREACH",
169
+ "ENETDOWN",
170
+ "EHOSTDOWN",
171
+ "ECONNABORTED",
172
+ "EPIPE",
173
+ "EACCES",
174
+ "EPERM",
175
+ "UND_ERR_CONNECT_TIMEOUT",
176
+ "UND_ERR_HEADERS_TIMEOUT",
177
+ "UND_ERR_BODY_TIMEOUT",
178
+ "UND_ERR_SOCKET",
179
+ "timeout",
112
180
  ]);
113
181
  function networkCode(value) {
114
- return typeof value === "string" && value.length <= 32 && NETWORK_ERROR_CODES.has(value)
115
- ? value
116
- : undefined;
182
+ return typeof value === "string" && value.length <= 32 && NETWORK_ERROR_CODES.has(value) ? value : undefined;
117
183
  }
118
184
  function sanitizedUnavailableDetails(details) {
119
185
  if (!details)
@@ -122,8 +188,7 @@ function sanitizedUnavailableDetails(details) {
122
188
  if (typeof details.host === "string") {
123
189
  try {
124
190
  const url = new URL(details.host);
125
- if ((url.protocol === "https:" || url.protocol === "http:") &&
126
- echoEncoder.encode(url.origin).length <= 253)
191
+ if ((url.protocol === "https:" || url.protocol === "http:") && echoEncoder.encode(url.origin).length <= 253)
127
192
  host = url.origin;
128
193
  }
129
194
  catch {
@@ -137,33 +202,73 @@ function sanitizedUnavailableDetails(details) {
137
202
  export function networkErrorCode(error) {
138
203
  if (!error || typeof error !== "object")
139
204
  return undefined;
140
- if (error instanceof Error &&
141
- (error.name === "AbortError" || error.name === "TimeoutError")) {
205
+ if (error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError")) {
142
206
  return "timeout";
143
207
  }
144
208
  const runtime = error;
145
209
  const cause = runtime.cause;
146
- return networkCode(runtime.code) ?? (cause && typeof cause === "object"
147
- ? networkCode(cause.code)
148
- : undefined);
210
+ return (networkCode(runtime.code) ??
211
+ (cause && typeof cause === "object" ? networkCode(cause.code) : undefined));
149
212
  }
150
- /** Use at a fetch boundary where the destination and transport failure are known. */
151
- export function unavailableCallError(cause, host, message = "Could not reach the downstream service.") {
152
- const code = networkErrorCode(cause);
213
+ /**
214
+ * Use at a fetch boundary where the destination and transport failure are
215
+ * known. The runtime's error is read for its errno and dropped, never kept as
216
+ * `cause`: its message and cause chain can quote the URL, headers, or body of
217
+ * the request that failed, and a logger that renders an error renders its
218
+ * cause. The origin and errno in `details` are what survives.
219
+ *
220
+ * The one failure kept is the request's own abort reason, when that is what
221
+ * the fetch rejected with: the caller wrote it, not the downstream, and it is
222
+ * how a cancelled request tells its reason from a network failure.
223
+ */
224
+ export function unavailableCallError(failure, host, message = "Could not reach the downstream service.", signal) {
225
+ const code = networkErrorCode(failure);
226
+ const ownReason = signal?.aborted === true && failure === signal.reason;
153
227
  return new ConnectorCallError("unavailable", message, {
154
- cause,
228
+ ...(ownReason ? { cause: failure } : {}),
155
229
  details: { ...(host ? { host } : {}), ...(code ? { code } : {}) },
156
230
  });
157
231
  }
232
+ /**
233
+ * A failure told in connecta's words because the original's text came from a
234
+ * downstream or authorization server, which can echo what the request carried
235
+ * or plant whatever it likes. There is no `cause`: the original is dropped
236
+ * whole, never masked.
237
+ *
238
+ * It is classified exactly as the original would have been. That verdict is
239
+ * read from the original once, here, and kept as two flags, so withholding
240
+ * the text moves no failure between `timeout`, retryable, and the caller's
241
+ * fallback code. Never wrap a `ConnectorCallError`: it already speaks in
242
+ * connecta's words and carries its own code.
243
+ */
244
+ export class WithheldTextError extends Error {
245
+ /** The original read as a timeout. */
246
+ timeout;
247
+ retryable;
248
+ constructor(message, original) {
249
+ super(message);
250
+ this.name = "WithheldTextError";
251
+ const verdict = classifyCallError(original);
252
+ this.timeout = verdict.code === "timeout";
253
+ this.retryable = verdict.retryable;
254
+ }
255
+ }
158
256
  const RETRYABLE_BY_CODE = {
159
257
  timeout: true,
160
258
  rate_limited: true,
161
259
  unavailable: true,
162
260
  auth_required: false,
261
+ downstream_oauth_required: false,
262
+ oauth_revocation_failed: false,
263
+ provider_permission_denied: false,
163
264
  invalid_args: false,
164
265
  not_found: false,
165
266
  conflict: false,
267
+ resource_template_ambiguous: false,
268
+ resource_match_budget_exceeded: false,
166
269
  input_required_unsupported: false,
270
+ input_required_invalid: false,
271
+ input_required_limit: false,
167
272
  connector_call_failed: false,
168
273
  };
169
274
  /** Entries a conflict's `current` map may carry. */
@@ -196,9 +301,9 @@ function normalizeRetryAfterMs(value) {
196
301
  }
197
302
  /**
198
303
  * Throw from `Connector.callTool` (or anything beneath it) to classify a
199
- * failure exactly. Untyped errors fall back to a message-text heuristic, so a
200
- * connector whose legitimate error text mentions "timeout" is misread as a
201
- * retryable timeout — this class is the escape hatch. `retryable` defaults per
304
+ * failure exactly. Untyped errors are non-retryable unless a runtime errno
305
+ * or abort identifies a transport failure. This class supplies the connector's
306
+ * reviewed verdict. `retryable` defaults per
202
307
  * code (timeout, rate_limited, and unavailable retry; the rest do not) and may
203
308
  * be overridden.
204
309
  *
@@ -220,6 +325,7 @@ export class ConnectorCallError extends Error {
220
325
  retryAfterMs;
221
326
  /** Bounded schema findings for `invalid_args`; never submitted values. */
222
327
  validation;
328
+ repair;
223
329
  /** Sanitized transport diagnostics for `unavailable` only. */
224
330
  details;
225
331
  /**
@@ -233,79 +339,51 @@ export class ConnectorCallError extends Error {
233
339
  this.code = code;
234
340
  this.retryable = opts.retryable ?? RETRYABLE_BY_CODE[code];
235
341
  this.retryAfterMs = normalizeRetryAfterMs(opts.retryAfterMs);
236
- this.details =
237
- code === "unavailable" ? sanitizedUnavailableDetails(opts.details) : undefined;
238
- this.validation =
239
- code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
342
+ this.details = code === "unavailable" ? sanitizedUnavailableDetails(opts.details) : undefined;
343
+ this.validation = code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
344
+ this.repair = code === "invalid_args" ? boundedRepair(opts.repair) : undefined;
240
345
  this.current = code === "conflict" ? boundedCurrent(opts.current) : undefined;
241
346
  }
242
347
  }
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
- */
348
+ /** Retryability of connecta framing depends only on its code. */
261
349
  export function framingError(code, message) {
262
350
  return {
263
351
  code,
264
352
  message,
265
- retryable: NEVER_RETRYABLE_FRAMING.has(code)
266
- ? false
267
- : messageLooksRetryable(message),
353
+ retryable: code === "timeout" || code === "unavailable" || code === "rate_limited",
268
354
  };
269
355
  }
270
- const RETRYABLE_MESSAGE_RE = /timeout|timed out|econnreset|econnrefused|temporar|rate.?limit|429|502|503|504|refcountedcanceler|different request/i;
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
- */
356
+ /** Typed connector verdicts and runtime facts only. Prose never changes a verdict. */
281
357
  export function classifyCallError(err, fallbackCode = "connector_call_failed") {
282
358
  if (err instanceof ConnectorCallError) {
283
359
  return {
284
360
  code: err.code,
285
361
  message: err.message,
286
362
  retryable: err.retryable,
287
- ...(err.retryAfterMs !== undefined
288
- ? { retryAfterMs: err.retryAfterMs }
289
- : {}),
363
+ ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
290
364
  ...(err.validation ? { validation: err.validation } : {}),
365
+ ...(err.repair ? { repair: err.repair } : {}),
291
366
  ...(err.details ? { details: err.details } : {}),
292
367
  ...(err.current ? { current: err.current } : {}),
293
368
  };
294
369
  }
295
- // An aborted fetch rejects with a DOMException named "AbortError" whose
296
- // message ("The operation was aborted", and variants across runtimes) matches
297
- // neither heuristic below — so a call the engine itself cancelled would read
298
- // as a non-retryable failure, the opposite of the truth. Note this also
299
- // covers an abort the connector triggered for its own reasons; running out of
300
- // time is by far the likelier cause and retryable/timeout is the safer read.
301
- if (err instanceof Error && err.name === "AbortError") {
302
- return { code: "timeout", message: err.message, retryable: true };
370
+ if (err instanceof WithheldTextError) {
371
+ return {
372
+ code: err.timeout ? "timeout" : fallbackCode,
373
+ message: err.message,
374
+ retryable: err.retryable,
375
+ };
303
376
  }
304
377
  const message = err instanceof Error ? err.message : String(err);
378
+ const network = networkErrorCode(err);
305
379
  return {
306
- code: TIMEOUT_MESSAGE_RE.test(message) ? "timeout" : fallbackCode,
380
+ code: network === "timeout" || network === "ETIMEDOUT" || network?.endsWith("_TIMEOUT")
381
+ ? "timeout"
382
+ : network
383
+ ? "unavailable"
384
+ : fallbackCode,
307
385
  message,
308
- retryable: RETRYABLE_MESSAGE_RE.test(message),
386
+ retryable: network !== undefined,
309
387
  };
310
388
  }
311
389
  export function msg(err) {