@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.
- package/CHANGELOG.md +91 -0
- package/README.md +3 -2
- package/bin/connecta.mjs +4 -8
- package/bin/version.mjs +1 -1
- package/dist/access-tokens.js +6 -4
- package/dist/agent-routes.js +231 -0
- package/dist/auth/downstream-oauth/consent.js +519 -0
- package/dist/auth/downstream-oauth/grant-store.js +439 -0
- package/dist/auth/downstream-oauth/refresh-coordinator.js +562 -0
- package/dist/auth/downstream-oauth/refresh-records.js +447 -0
- package/dist/auth/downstream-oauth/sdk-hooks.js +242 -0
- package/dist/auth/downstream-oauth.js +66 -2382
- package/dist/auth/native.js +37 -0
- package/dist/auth/oauth-grant.js +13 -0
- package/dist/auth/static-oauth.js +153 -131
- package/dist/auth-elicitation.js +7 -1
- package/dist/authorization-handoff.js +11 -5
- package/dist/catalog-cache.js +219 -59
- package/dist/catalog-policy.js +18 -0
- package/dist/catalog-service.js +284 -47
- package/dist/catalog.js +18 -2
- package/dist/config.d.ts +16 -11
- package/dist/config.js +9 -6
- package/dist/connector-caller.d.ts +1 -1
- package/dist/connector-health.js +59 -0
- package/dist/connector-status.js +117 -0
- package/dist/connectors/api-connector.d.ts +7 -2
- package/dist/connectors/api-connector.js +7 -4
- package/dist/connectors/negotiation-cache.js +22 -4
- package/dist/connectors/remote-mcp/call.js +164 -0
- package/dist/connectors/remote-mcp/catalog.js +278 -0
- package/dist/connectors/remote-mcp/config.js +263 -0
- package/dist/connectors/remote-mcp/connection.js +682 -0
- package/dist/connectors/remote-mcp/errors.js +488 -0
- package/dist/connectors/remote-mcp/oauth.js +473 -0
- package/dist/connectors/remote-mcp/resources.js +473 -0
- package/dist/connectors/remote-mcp/runtime.js +1 -0
- package/dist/connectors/remote-mcp/transport.js +555 -0
- package/dist/connectors/remote-mcp.js +62 -2863
- package/dist/credential-contract.d.ts +23 -0
- package/dist/credential-reads.js +17 -0
- package/dist/credential-verification.js +53 -0
- package/dist/credentials.d.ts +7 -0
- package/dist/credentials.js +60 -25
- package/dist/describe-config.d.ts +12 -2
- package/dist/describe-config.js +2 -0
- package/dist/discovery-health.js +199 -0
- package/dist/downstream-input.js +2 -0
- package/dist/errors.d.ts +55 -17
- package/dist/errors.js +95 -41
- package/dist/execute.js +152 -114
- package/dist/executor-result.js +3 -1
- package/dist/guest-functions.js +83 -0
- package/dist/guest-runtime.js +60 -19
- package/dist/guest-types.d.ts +19 -5
- package/dist/http/argument-problems.js +35 -0
- package/dist/http/errors.js +5 -4
- package/dist/http/fields.js +192 -13
- package/dist/http/hatch-response.js +73 -0
- package/dist/http/hatch.js +88 -23
- package/dist/http/oauth.js +3 -2
- package/dist/http/provider.js +32 -4
- package/dist/http/safety.js +8 -0
- package/dist/http/tools.js +44 -23
- package/dist/index.d.ts +1 -1
- package/dist/index.js +9 -2
- package/dist/invocation.js +26 -8
- package/dist/membership.d.ts +13 -5
- package/dist/membership.js +34 -2
- package/dist/meta-tools.js +54 -31
- package/dist/native-recovery.js +4 -16
- package/dist/native-tools.js +5 -2
- package/dist/oauth-sealing.js +10 -0
- package/dist/operation-vocabulary.js +135 -13
- package/dist/operator-record.d.ts +2 -2
- package/dist/operator-record.js +1 -0
- package/dist/operator-ui/contract.d.ts +10 -0
- package/dist/operator-ui/generated.js +2 -2
- package/dist/operator-ui/model.d.ts +22 -1
- package/dist/provider-call-facts.js +6 -2
- package/dist/providers/_shared/rest/operation-index.js +48 -50
- package/dist/providers/_shared/rest/value-safety.js +80 -0
- package/dist/providers/breeze/api.js +7 -1
- package/dist/providers/breeze/skill.generated.js +1 -1
- package/dist/providers/breeze/tools.js +4 -3
- package/dist/providers/ccb/api.js +2 -1
- package/dist/providers/ccb/index.js +5 -0
- package/dist/providers/ccb/skill.generated.js +1 -1
- package/dist/providers/cloudflare/api.js +8 -1
- package/dist/providers/cloudflare/skill.generated.js +1 -1
- package/dist/providers/docs/lib/schemas.js +24 -22
- package/dist/providers/docs/safety.js +2 -0
- package/dist/providers/docs/skill.generated.js +1 -1
- package/dist/providers/docs/tools.js +2 -4
- package/dist/providers/drive/api.js +1 -0
- package/dist/providers/drive/lib/contracts.js +8 -5
- package/dist/providers/drive/skill.generated.js +1 -1
- package/dist/providers/drive/tools.js +11 -16
- package/dist/providers/forms/api.js +1 -0
- package/dist/providers/forms/skill.generated.js +1 -1
- package/dist/providers/forms/tools.js +10 -7
- package/dist/providers/github/api.js +1 -0
- package/dist/providers/github/lib/discovery.js +1 -1
- package/dist/providers/github/skill.generated.js +1 -1
- package/dist/providers/github/tools.js +61 -17
- package/dist/providers/gmail/lib/schemas.js +60 -50
- package/dist/providers/gmail/skill.generated.js +1 -1
- package/dist/providers/gmail/tools.js +7 -5
- package/dist/providers/granola/index.js +2 -0
- package/dist/providers/granola/skill.generated.js +1 -1
- package/dist/providers/overflow/api.js +7 -1
- package/dist/providers/overflow/skill.generated.js +1 -1
- package/dist/providers/planning-center/api.js +3 -1
- package/dist/providers/planning-center/lib/constants.d.ts +1 -1
- package/dist/providers/planning-center/skill.generated.js +1 -1
- package/dist/providers/quickbooks/safety.js +80 -39
- package/dist/providers/quickbooks/skill.generated.js +1 -1
- package/dist/providers/sheets/api.js +1 -0
- package/dist/providers/sheets/skill.generated.js +1 -1
- package/dist/providers/sheets/tools.js +13 -14
- package/dist/providers/slides/skill.generated.js +1 -1
- package/dist/providers/slides/tools.js +15 -13
- package/dist/providers/stripe/skill.generated.js +1 -1
- package/dist/providers/tithely/api.js +3 -1
- package/dist/providers/tithely/skill.generated.js +1 -1
- package/dist/providers/vercel/api.js +1 -1
- package/dist/providers/vercel/skill.generated.js +1 -1
- package/dist/providers/vercel/tools.js +4 -3
- package/dist/registry.d.ts +10 -4
- package/dist/registry.js +41 -13
- package/dist/routes/credentials.js +129 -60
- package/dist/routes/dispatch.js +5 -1
- package/dist/routes/mcp.js +30 -14
- package/dist/routes/operator.js +2 -2
- package/dist/routes/shared.d.ts +6 -1
- package/dist/routes/shared.js +7 -1
- package/dist/routes/ui-config.js +2 -2
- package/dist/routes/ui-data.js +126 -20
- package/dist/routes/ui.js +16 -0
- package/dist/runtime/call.js +7 -2
- package/dist/runtime/native-storage.js +12 -0
- package/dist/runtime/request-reads.js +207 -0
- package/dist/runtime/request-scope.js +16 -0
- package/dist/runtime/storage.js +12 -0
- package/dist/skills.js +37 -20
- package/dist/storage/keys.js +53 -3
- package/dist/storage/memory.js +8 -2
- package/dist/storage/sql-native.js +53 -1
- package/dist/storage/sql.js +12 -2
- package/dist/storage-digest.js +32 -0
- package/dist/timeout.js +8 -0
- package/dist/types.d.ts +33 -0
- package/dist/usage-guide.js +16 -35
- package/dist/validate.d.ts +3 -0
- package/dist/validate.js +220 -158
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/write-outcome.js +0 -3
- package/documentation/README.md +13 -13
- package/documentation/architecture.md +385 -20
- package/documentation/auth.md +233 -64
- package/documentation/code-mode.md +122 -39
- package/documentation/deploying.md +6 -3
- package/documentation/integrating.md +16 -2
- package/documentation/meta-tools.md +240 -49
- package/documentation/migration-0.33.md +5 -1
- package/documentation/migration-0.34.md +3 -1
- package/documentation/operator-tests.md +1 -1
- package/documentation/operator-ui.md +105 -12
- package/documentation/pool-membership-upgrade.md +44 -0
- package/documentation/providers.md +105 -0
- package/examples/worker/AGENTS.md +10 -10
- package/examples/worker/README.md +4 -3
- package/examples/worker/src/connecta.config.ts +1 -0
- package/guides/connecting-agents.md +2 -1
- package/guides/how-it-works.md +4 -2
- package/package.json +1 -1
- package/templates/node/AGENTS.md +13 -12
- package/templates/node/package.json +1 -1
- 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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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?:
|
|
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
|
-
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
67
|
-
const
|
|
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
|
|
152
|
-
|
|
139
|
+
function plainJson(value) {
|
|
140
|
+
try {
|
|
141
|
+
return JSON.parse(JSON.stringify(value));
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
153
144
|
return undefined;
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
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
|
|
162
|
-
|
|
163
|
-
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
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
|
-
/**
|
|
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 } : {}),
|