@zackbart/connecta 0.38.0 → 0.40.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 (180) hide show
  1. package/CHANGELOG.md +91 -0
  2. package/README.md +3 -2
  3. package/bin/connecta.mjs +4 -8
  4. package/bin/version.mjs +1 -1
  5. package/dist/access-tokens.js +6 -4
  6. package/dist/agent-routes.js +231 -0
  7. package/dist/auth/downstream-oauth/consent.js +519 -0
  8. package/dist/auth/downstream-oauth/grant-store.js +439 -0
  9. package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
  10. package/dist/auth/downstream-oauth/refresh-records.js +447 -0
  11. package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
  12. package/dist/auth/downstream-oauth.js +66 -2382
  13. package/dist/auth/native.js +37 -0
  14. package/dist/auth/oauth-grant.js +13 -0
  15. package/dist/auth/static-oauth.js +153 -131
  16. package/dist/auth-elicitation.js +7 -1
  17. package/dist/authorization-handoff.js +11 -5
  18. package/dist/catalog-cache.js +219 -59
  19. package/dist/catalog-policy.js +18 -0
  20. package/dist/catalog-service.js +284 -47
  21. package/dist/catalog.js +18 -2
  22. package/dist/config.d.ts +16 -11
  23. package/dist/config.js +9 -6
  24. package/dist/connector-caller.d.ts +1 -1
  25. package/dist/connector-health.js +59 -0
  26. package/dist/connector-status.js +117 -0
  27. package/dist/connectors/api-connector.d.ts +7 -2
  28. package/dist/connectors/api-connector.js +7 -4
  29. package/dist/connectors/negotiation-cache.js +22 -4
  30. package/dist/connectors/remote-mcp/call.js +164 -0
  31. package/dist/connectors/remote-mcp/catalog.js +278 -0
  32. package/dist/connectors/remote-mcp/config.js +263 -0
  33. package/dist/connectors/remote-mcp/connection.js +682 -0
  34. package/dist/connectors/remote-mcp/errors.js +488 -0
  35. package/dist/connectors/remote-mcp/oauth.js +473 -0
  36. package/dist/connectors/remote-mcp/resources.js +473 -0
  37. package/dist/connectors/remote-mcp/runtime.js +1 -0
  38. package/dist/connectors/remote-mcp/transport.js +555 -0
  39. package/dist/connectors/remote-mcp.js +62 -2863
  40. package/dist/credential-contract.d.ts +23 -0
  41. package/dist/credential-reads.js +17 -0
  42. package/dist/credential-verification.js +53 -0
  43. package/dist/credentials.d.ts +7 -0
  44. package/dist/credentials.js +60 -25
  45. package/dist/describe-config.d.ts +12 -2
  46. package/dist/describe-config.js +2 -0
  47. package/dist/discovery-health.js +199 -0
  48. package/dist/downstream-input.js +2 -0
  49. package/dist/errors.d.ts +55 -17
  50. package/dist/errors.js +95 -41
  51. package/dist/execute.js +152 -114
  52. package/dist/executor-result.js +3 -1
  53. package/dist/guest-functions.js +83 -0
  54. package/dist/guest-runtime.js +60 -19
  55. package/dist/guest-types.d.ts +19 -5
  56. package/dist/http/argument-problems.js +35 -0
  57. package/dist/http/errors.js +5 -4
  58. package/dist/http/fields.js +192 -13
  59. package/dist/http/hatch-response.js +73 -0
  60. package/dist/http/hatch.js +88 -23
  61. package/dist/http/oauth.js +3 -2
  62. package/dist/http/provider.js +32 -4
  63. package/dist/http/safety.js +8 -0
  64. package/dist/http/tools.js +44 -23
  65. package/dist/index.d.ts +1 -1
  66. package/dist/index.js +9 -2
  67. package/dist/invocation.js +26 -8
  68. package/dist/membership.d.ts +13 -5
  69. package/dist/membership.js +34 -2
  70. package/dist/meta-tools.js +54 -31
  71. package/dist/native-recovery.js +4 -16
  72. package/dist/native-tools.js +5 -2
  73. package/dist/oauth-sealing.js +10 -0
  74. package/dist/operation-vocabulary.js +135 -13
  75. package/dist/operator-record.d.ts +2 -2
  76. package/dist/operator-record.js +1 -0
  77. package/dist/operator-ui/contract.d.ts +10 -0
  78. package/dist/operator-ui/generated.js +2 -2
  79. package/dist/operator-ui/model.d.ts +22 -1
  80. package/dist/provider-call-facts.js +6 -2
  81. package/dist/providers/_shared/rest/operation-index.js +48 -50
  82. package/dist/providers/_shared/rest/value-safety.js +80 -0
  83. package/dist/providers/breeze/api.js +7 -1
  84. package/dist/providers/breeze/skill.generated.js +1 -1
  85. package/dist/providers/breeze/tools.js +4 -3
  86. package/dist/providers/ccb/api.js +2 -1
  87. package/dist/providers/ccb/index.js +5 -0
  88. package/dist/providers/ccb/skill.generated.js +1 -1
  89. package/dist/providers/cloudflare/api.js +8 -1
  90. package/dist/providers/cloudflare/skill.generated.js +1 -1
  91. package/dist/providers/docs/lib/schemas.js +24 -22
  92. package/dist/providers/docs/safety.js +2 -0
  93. package/dist/providers/docs/skill.generated.js +1 -1
  94. package/dist/providers/docs/tools.js +2 -4
  95. package/dist/providers/drive/api.js +1 -0
  96. package/dist/providers/drive/lib/contracts.js +8 -5
  97. package/dist/providers/drive/skill.generated.js +1 -1
  98. package/dist/providers/drive/tools.js +11 -16
  99. package/dist/providers/forms/api.js +1 -0
  100. package/dist/providers/forms/skill.generated.js +1 -1
  101. package/dist/providers/forms/tools.js +10 -7
  102. package/dist/providers/github/api.js +1 -0
  103. package/dist/providers/github/lib/discovery.js +1 -1
  104. package/dist/providers/github/skill.generated.js +1 -1
  105. package/dist/providers/github/tools.js +61 -17
  106. package/dist/providers/gmail/lib/schemas.js +60 -50
  107. package/dist/providers/gmail/skill.generated.js +1 -1
  108. package/dist/providers/gmail/tools.js +7 -5
  109. package/dist/providers/granola/index.js +2 -0
  110. package/dist/providers/granola/skill.generated.js +1 -1
  111. package/dist/providers/overflow/api.js +7 -1
  112. package/dist/providers/overflow/skill.generated.js +1 -1
  113. package/dist/providers/planning-center/api.js +3 -1
  114. package/dist/providers/planning-center/lib/constants.d.ts +1 -1
  115. package/dist/providers/planning-center/skill.generated.js +1 -1
  116. package/dist/providers/quickbooks/safety.js +80 -39
  117. package/dist/providers/quickbooks/skill.generated.js +1 -1
  118. package/dist/providers/sheets/api.js +1 -0
  119. package/dist/providers/sheets/skill.generated.js +1 -1
  120. package/dist/providers/sheets/tools.js +13 -14
  121. package/dist/providers/slides/skill.generated.js +1 -1
  122. package/dist/providers/slides/tools.js +15 -13
  123. package/dist/providers/stripe/skill.generated.js +1 -1
  124. package/dist/providers/tithely/api.js +3 -1
  125. package/dist/providers/tithely/skill.generated.js +1 -1
  126. package/dist/providers/vercel/api.js +1 -1
  127. package/dist/providers/vercel/skill.generated.js +1 -1
  128. package/dist/providers/vercel/tools.js +4 -3
  129. package/dist/registry.d.ts +10 -4
  130. package/dist/registry.js +41 -13
  131. package/dist/routes/credentials.js +129 -60
  132. package/dist/routes/dispatch.js +5 -1
  133. package/dist/routes/mcp.js +30 -14
  134. package/dist/routes/operator.js +2 -2
  135. package/dist/routes/shared.d.ts +6 -1
  136. package/dist/routes/shared.js +7 -1
  137. package/dist/routes/ui-config.js +2 -2
  138. package/dist/routes/ui-data.js +126 -20
  139. package/dist/routes/ui.js +16 -0
  140. package/dist/runtime/call.js +7 -2
  141. package/dist/runtime/native-storage.js +12 -0
  142. package/dist/runtime/request-reads.js +207 -0
  143. package/dist/runtime/request-scope.js +16 -0
  144. package/dist/runtime/storage.js +12 -0
  145. package/dist/skills.js +37 -20
  146. package/dist/storage/keys.js +53 -3
  147. package/dist/storage/memory.js +8 -2
  148. package/dist/storage/sql-native.js +53 -1
  149. package/dist/storage/sql.js +12 -2
  150. package/dist/storage-digest.js +32 -0
  151. package/dist/timeout.js +8 -0
  152. package/dist/types.d.ts +33 -0
  153. package/dist/usage-guide.js +16 -35
  154. package/dist/validate.d.ts +3 -0
  155. package/dist/validate.js +220 -158
  156. package/dist/version.d.ts +1 -1
  157. package/dist/version.js +1 -1
  158. package/dist/write-outcome.js +0 -3
  159. package/documentation/README.md +13 -13
  160. package/documentation/architecture.md +385 -20
  161. package/documentation/auth.md +233 -64
  162. package/documentation/code-mode.md +122 -39
  163. package/documentation/deploying.md +6 -3
  164. package/documentation/integrating.md +16 -2
  165. package/documentation/meta-tools.md +240 -49
  166. package/documentation/migration-0.33.md +5 -1
  167. package/documentation/migration-0.34.md +3 -1
  168. package/documentation/operator-tests.md +1 -1
  169. package/documentation/operator-ui.md +105 -12
  170. package/documentation/pool-membership-upgrade.md +44 -0
  171. package/documentation/providers.md +105 -0
  172. package/examples/worker/AGENTS.md +10 -10
  173. package/examples/worker/README.md +4 -3
  174. package/examples/worker/src/connecta.config.ts +1 -0
  175. package/guides/connecting-agents.md +2 -1
  176. package/guides/how-it-works.md +4 -2
  177. package/package.json +1 -1
  178. package/templates/node/AGENTS.md +13 -12
  179. package/templates/node/package.json +1 -1
  180. package/templates/node/src/connecta.config.ts +1 -0
package/dist/errors.d.ts CHANGED
@@ -36,21 +36,51 @@ export type ConnectorCallErrorCode = "timeout" | "auth_required" | "downstream_o
36
36
  export type ClassificationCode = ConnectorCallErrorCode | ExecutorAdmissionErrorCode | "cancelled" | "unknown_address" | "unknown_tool" | "ambiguous_tool_alias" | "catalog_lookup_failed" | "result_too_large" | "destructive_tool_requires_approval" | "read_only_endpoint" | "auth_replay_refused" | "write_outcome_unknown" | "result_processing_failed" | "budget_exceeded" | "executor_failed" | "program_error";
37
37
  /** `value` when it is a code connecta assigns, else undefined. */
38
38
  export declare function classificationCode(value: unknown): ClassificationCode | undefined;
39
- /** One bounded, payload-free explanation of an input-schema mismatch. */
39
+ /**
40
+ * One bounded fix for an argument. `expected` states the actual bound, allowed
41
+ * values or shape; `received` is the submitted JSON type, or a submitted number
42
+ * when its schema position is not writeOnly. Never a submitted string.
43
+ */
40
44
  export interface ArgumentValidationIssue {
41
45
  /** JSON Pointer into the submitted arguments; "/" means the root value. */
42
46
  path: string;
43
- /** JSON Schema keyword that rejected the argument. */
44
- code: string;
45
- /** Expected shape only — never the submitted value. */
47
+ /** What the argument must be, e.g. `at least 5` or `one of "fast", "slow"`. */
46
48
  expected: string;
49
+ /** What arrived, e.g. `string`, `missing` or `4`. */
50
+ received?: string;
51
+ /**
52
+ * @deprecated Accepted from custom connectors for compatibility and no longer
53
+ * returned; `expected` carries the constraint.
54
+ */
55
+ code?: string;
47
56
  }
57
+ /** A conditional requirement read from the published schema. */
58
+ export interface ArgumentConditionalRequirement {
59
+ path: string;
60
+ condition: unknown;
61
+ required: string[];
62
+ }
63
+ /** Every bounded argument finding and one corrected example call. */
48
64
  export interface ArgumentValidationDetails {
49
65
  issues: ArgumentValidationIssue[];
50
- /** More findings existed but were omitted from the bounded response. */
66
+ /** The tool's top-level argument names. */
67
+ acceptedKeys?: string[];
68
+ conditionalRequirements?: ArgumentConditionalRequirement[];
69
+ /**
70
+ * One complete corrected call. Placeholder values look like `<owner>/<repo>`;
71
+ * an example is omitted rather than guessed.
72
+ */
73
+ example?: unknown;
74
+ /** Why no example accompanies these findings. */
75
+ exampleUnavailable?: string;
76
+ /** More findings or detail existed but were omitted from the bounded response. */
51
77
  truncated?: true;
52
78
  }
53
- /** Agent-only facts from the published schema, never operator record fields. */
79
+ /**
80
+ * @deprecated Pass these facts in `validation`, which connecta now returns as
81
+ * the single argument-recovery envelope. A `repair` passed to
82
+ * {@link ConnectorCallError} is folded into `validation`.
83
+ */
54
84
  export interface ArgumentRepairDetails {
55
85
  acceptedKeys?: string[];
56
86
  issues: Array<{
@@ -60,17 +90,17 @@ export interface ArgumentRepairDetails {
60
90
  enumValues?: unknown[];
61
91
  bounds?: Record<string, number>;
62
92
  }>;
63
- conditionalRequirements?: Array<{
64
- path: string;
65
- condition: unknown;
66
- required: string[];
67
- }>;
68
- /** Synthesized from the schema and checked by the same validator. */
93
+ conditionalRequirements?: ArgumentConditionalRequirement[];
69
94
  example?: unknown;
70
95
  exampleUnavailable?: string;
71
96
  truncated?: true;
72
97
  }
73
- export declare const MAX_ARGUMENT_VALIDATION_ISSUES = 3;
98
+ /**
99
+ * Up to eight findings per refusal: enough for every argument of a maintained
100
+ * tool (the widest declare fewer than eight top-level arguments) while each
101
+ * finding stays a few hundred bytes inside the 4 KiB envelope below.
102
+ */
103
+ export declare const MAX_ARGUMENT_VALIDATION_ISSUES = 8;
74
104
  /**
75
105
  * Clamp a string to a UTF-8 byte budget, appending `…` when it clipped.
76
106
  * Short strings — the common case, and the one that has to stay exact — are
@@ -87,6 +117,12 @@ export declare function echoedCallArgs(args: unknown, schema?: JsonSchema): {
87
117
  args?: unknown;
88
118
  argsRedacted?: true;
89
119
  };
120
+ /** A JSON Schema bound keyword as an agent-readable constraint with its number. */
121
+ export declare function boundText(keyword: string, bound: unknown): string | undefined;
122
+ /** Up to twelve items, then a count. */
123
+ export declare function listed(items: readonly string[]): string;
124
+ /** One agent-readable clause per finding, for the error message. */
125
+ export declare function issueSummary(issues: readonly ArgumentValidationIssue[]): string;
90
126
  /** Optional transport diagnostics; never a URL path or raw runtime message. */
91
127
  interface UnavailableDetails {
92
128
  /**
@@ -169,9 +205,11 @@ export declare class ConnectorCallError extends Error {
169
205
  * of the wire format is `classifyCallError`'s job, not this constructor's.
170
206
  */
171
207
  readonly retryAfterMs: number | undefined;
172
- /** Bounded schema findings for `invalid_args`; never submitted values. */
208
+ /**
209
+ * Every bounded argument finding for `invalid_args`, with one corrected
210
+ * example call when it can be built without guessing.
211
+ */
173
212
  readonly validation: ArgumentValidationDetails | undefined;
174
- readonly repair: ArgumentRepairDetails | undefined;
175
213
  /**
176
214
  * Sanitized transport diagnostics, for `unavailable` and for a write whose
177
215
  * outcome is unknown (a timeout's errno, an abort's class).
@@ -195,6 +233,7 @@ export declare class ConnectorCallError extends Error {
195
233
  retryAfterMs?: number;
196
234
  cause?: unknown;
197
235
  validation?: ArgumentValidationDetails;
236
+ /** @deprecated Pass these facts in `validation`; they are folded into it. */
198
237
  repair?: ArgumentRepairDetails;
199
238
  details?: UnavailableDetails;
200
239
  current?: Readonly<Record<string, number>>;
@@ -227,9 +266,8 @@ export interface CallErrorDetails extends Partial<AuthorizationHandoff> {
227
266
  retryable: boolean;
228
267
  /** Connector-known wait window; see {@link ConnectorCallError.retryAfterMs}. */
229
268
  retryAfterMs?: number;
230
- /** Bounded input-schema findings; paths and expectations, never values. */
269
+ /** Every bounded argument finding and one corrected example call. */
231
270
  validation?: ArgumentValidationDetails;
232
- repair?: ArgumentRepairDetails;
233
271
  /** On a `conflict`: where each thing the write touched stands now. */
234
272
  current?: Readonly<Record<string, number>>;
235
273
  /** Connector whose failed operation needs recovery. */
package/dist/errors.js CHANGED
@@ -43,28 +43,16 @@ export function classificationCode(value) {
43
43
  ? value
44
44
  : undefined;
45
45
  }
46
- /** Drop oversized detail whole; clipping keys or examples changes their meaning. */
47
- function boundedRepair(details) {
48
- if (!details)
49
- return undefined;
50
- try {
51
- const text = JSON.stringify(details);
52
- return new TextEncoder().encode(text).length <= 4096
53
- ? JSON.parse(text)
54
- : {
55
- issues: [],
56
- truncated: true,
57
- exampleUnavailable: "Repair detail exceeds the response budget. Inspect the published inputSchema.",
58
- };
59
- }
60
- catch {
61
- return undefined;
62
- }
63
- }
64
- export const MAX_ARGUMENT_VALIDATION_ISSUES = 3;
46
+ /**
47
+ * Up to eight findings per refusal: enough for every argument of a maintained
48
+ * tool (the widest declare fewer than eight top-level arguments) while each
49
+ * finding stays a few hundred bytes inside the 4 KiB envelope below.
50
+ */
51
+ export const MAX_ARGUMENT_VALIDATION_ISSUES = 8;
65
52
  const MAX_ARGUMENT_ISSUE_PATH_CHARS = 256;
66
- const MAX_ARGUMENT_ISSUE_CODE_CHARS = 64;
67
- const MAX_ARGUMENT_ISSUE_EXPECTED_CHARS = 128;
53
+ const MAX_ARGUMENT_ISSUE_EXPECTED_CHARS = 256;
54
+ const MAX_ARGUMENT_ISSUE_RECEIVED_CHARS = 64;
55
+ const MAX_ARGUMENT_VALIDATION_BYTES = 4096;
68
56
  function boundedIssueText(value, maxChars) {
69
57
  if (value.length <= maxChars)
70
58
  return { value, truncated: false };
@@ -148,25 +136,91 @@ export function echoedCallArgs(args, schema) {
148
136
  ? { argsRedacted: true }
149
137
  : {};
150
138
  }
151
- function boundedValidation(details) {
152
- if (!details)
139
+ function plainJson(value) {
140
+ try {
141
+ return JSON.parse(JSON.stringify(value));
142
+ }
143
+ catch {
153
144
  return undefined;
154
- let truncated = details.truncated === true || details.issues.length > MAX_ARGUMENT_VALIDATION_ISSUES;
155
- const issues = details.issues.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES).map((issue) => {
156
- const path = boundedIssueText(issue.path, MAX_ARGUMENT_ISSUE_PATH_CHARS);
157
- const code = boundedIssueText(issue.code, MAX_ARGUMENT_ISSUE_CODE_CHARS);
158
- const expected = boundedIssueText(issue.expected, MAX_ARGUMENT_ISSUE_EXPECTED_CHARS);
159
- truncated ||= path.truncated || code.truncated || expected.truncated;
145
+ }
146
+ }
147
+ const BOUND_WORDS = {
148
+ minimum: "at least",
149
+ maximum: "at most",
150
+ exclusiveMinimum: "greater than",
151
+ exclusiveMaximum: "less than",
152
+ multipleOf: "a multiple of",
153
+ };
154
+ /** A JSON Schema bound keyword as an agent-readable constraint with its number. */
155
+ export function boundText(keyword, bound) {
156
+ const [, side, unit] = /^(min|max)(Length|Items|Properties)$/.exec(keyword) ?? [];
157
+ const words = side ? `at ${side === "min" ? "least" : "most"}` : BOUND_WORDS[keyword];
158
+ return typeof bound === "number" && words
159
+ ? `${words} ${bound}${unit ? ` ${unit === "Length" ? "characters" : unit.toLowerCase()}` : ""}`
160
+ : undefined;
161
+ }
162
+ /** Up to twelve items, then a count. */
163
+ export function listed(items) {
164
+ return items.length > 12 ? `${items.slice(0, 12).join(", ")}, … (${items.length} in all)` : items.join(", ");
165
+ }
166
+ /** One agent-readable clause per finding, for the error message. */
167
+ export function issueSummary(issues) {
168
+ return issues
169
+ .map((issue) => `${issue.path}: expected ${issue.expected}${issue.received ? `, received ${issue.received}` : ""}`)
170
+ .join("; ");
171
+ }
172
+ /**
173
+ * Bound argument findings into the one recovery envelope. A legacy `repair`
174
+ * contributes its received types and schema facts. The envelope is capped at
175
+ * 4 KiB: optional detail goes first, then the example, then trailing findings,
176
+ * so what remains is always whole.
177
+ */
178
+ function boundedValidation(details, repair) {
179
+ if (!details && !repair)
180
+ return undefined;
181
+ const source = { ...repair, ...details };
182
+ const all = (details?.issues ?? []).filter((issue, index, list) => typeof issue?.path === "string" &&
183
+ typeof issue.expected === "string" &&
184
+ list.findIndex((other) => other.path === issue.path && other.expected === issue.expected) === index);
185
+ let truncated = source.truncated === true || all.length > MAX_ARGUMENT_VALIDATION_ISSUES;
186
+ const clip = (value, max) => {
187
+ const bounded = boundedIssueText(value, max);
188
+ truncated ||= bounded.truncated;
189
+ return bounded.value;
190
+ };
191
+ const issues = all.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES).map(({ path, expected, received }) => {
192
+ received ??= repair?.issues?.find((legacy) => legacy?.path === path)?.receivedType;
160
193
  return {
161
- path: path.value,
162
- code: code.value,
163
- expected: expected.value,
194
+ path: clip(path, MAX_ARGUMENT_ISSUE_PATH_CHARS),
195
+ expected: clip(expected, MAX_ARGUMENT_ISSUE_EXPECTED_CHARS),
196
+ ...(typeof received === "string" ? { received: clip(received, MAX_ARGUMENT_ISSUE_RECEIVED_CHARS) } : {}),
164
197
  };
165
198
  });
166
- return {
167
- issues,
168
- ...(truncated ? { truncated: true } : {}),
169
- };
199
+ const result = { issues };
200
+ if (Array.isArray(source.acceptedKeys) && source.acceptedKeys.length)
201
+ result.acceptedKeys = source.acceptedKeys.filter((key) => typeof key === "string");
202
+ if (Array.isArray(source.conditionalRequirements) && source.conditionalRequirements.length)
203
+ result.conditionalRequirements = plainJson(source.conditionalRequirements);
204
+ const example = Object.hasOwn(source, "example") ? plainJson(source.example) : undefined;
205
+ if (example !== undefined)
206
+ result.example = example;
207
+ else if (typeof source.exampleUnavailable === "string")
208
+ result.exampleUnavailable = clip(source.exampleUnavailable, MAX_ARGUMENT_ISSUE_EXPECTED_CHARS);
209
+ const fits = () => echoEncoder.encode(JSON.stringify(result)).length <= MAX_ARGUMENT_VALIDATION_BYTES - 20;
210
+ if (!fits()) {
211
+ truncated = true;
212
+ delete result.conditionalRequirements;
213
+ delete result.acceptedKeys;
214
+ if (result.example !== undefined && !fits()) {
215
+ delete result.example;
216
+ result.exampleUnavailable = "The example exceeds the response budget. Inspect the published inputSchema.";
217
+ }
218
+ }
219
+ while (!fits() && issues.length > 1)
220
+ issues.pop();
221
+ if (truncated)
222
+ result.truncated = true;
223
+ return result;
170
224
  }
171
225
  /** The network errnos `networkErrorCode` reports, and `timeout`. */
172
226
  export const NETWORK_ERROR_CODES = new Set([
@@ -344,9 +398,11 @@ export class ConnectorCallError extends Error {
344
398
  * of the wire format is `classifyCallError`'s job, not this constructor's.
345
399
  */
346
400
  retryAfterMs;
347
- /** Bounded schema findings for `invalid_args`; never submitted values. */
401
+ /**
402
+ * Every bounded argument finding for `invalid_args`, with one corrected
403
+ * example call when it can be built without guessing.
404
+ */
348
405
  validation;
349
- repair;
350
406
  /**
351
407
  * Sanitized transport diagnostics, for `unavailable` and for a write whose
352
408
  * outcome is unknown (a timeout's errno, an abort's class).
@@ -373,8 +429,7 @@ export class ConnectorCallError extends Error {
373
429
  this.retryAfterMs = normalizeRetryAfterMs(opts.retryAfterMs);
374
430
  this.details =
375
431
  code === "unavailable" || opts.writeOutcome === "unknown" ? sanitizedUnavailableDetails(opts.details) : undefined;
376
- this.validation = code === "invalid_args" ? boundedValidation(opts.validation) : undefined;
377
- this.repair = code === "invalid_args" ? boundedRepair(opts.repair) : undefined;
432
+ this.validation = code === "invalid_args" ? boundedValidation(opts.validation, opts.repair) : undefined;
378
433
  this.current = code === "conflict" ? boundedCurrent(opts.current) : undefined;
379
434
  this.writeOutcome = opts.writeOutcome === "unknown" ? "unknown" : undefined;
380
435
  }
@@ -482,7 +537,6 @@ export function classifyWithoutAdvice(err, fallbackCode = "connector_call_failed
482
537
  retryable: err.retryable,
483
538
  ...(err.retryAfterMs !== undefined ? { retryAfterMs: err.retryAfterMs } : {}),
484
539
  ...(err.validation ? { validation: err.validation } : {}),
485
- ...(err.repair ? { repair: err.repair } : {}),
486
540
  ...(err.details ? { details: err.details } : {}),
487
541
  ...(err.current ? { current: err.current } : {}),
488
542
  ...(err.writeOutcome ? { writeOutcome: err.writeOutcome } : {}),