@zackbart/connecta 0.14.2 → 0.15.1
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 +89 -0
- package/dist/catalog-service.d.ts.map +1 -1
- package/dist/catalog-service.js +104 -56
- package/dist/catalog-service.js.map +1 -1
- package/dist/catalog.d.ts +8 -2
- package/dist/catalog.d.ts.map +1 -1
- package/dist/catalog.js +58 -9
- package/dist/catalog.js.map +1 -1
- package/dist/connectors/api.d.ts +4 -4
- package/dist/connectors/api.js +4 -4
- package/dist/execute.d.ts.map +1 -1
- package/dist/execute.js +8 -7
- package/dist/execute.js.map +1 -1
- package/dist/meta-tools.js +1 -1
- package/dist/meta-tools.js.map +1 -1
- package/dist/providers/cloudflare.d.ts +5 -1
- package/dist/providers/cloudflare.d.ts.map +1 -1
- package/dist/providers/cloudflare.js +203 -70
- package/dist/providers/cloudflare.js.map +1 -1
- package/dist/providers/linear.d.ts.map +1 -1
- package/dist/providers/linear.js +4 -3
- package/dist/providers/linear.js.map +1 -1
- package/dist/providers/mixpanel.d.ts.map +1 -1
- package/dist/providers/mixpanel.js +4 -3
- package/dist/providers/mixpanel.js.map +1 -1
- package/dist/providers/stripe.d.ts.map +1 -1
- package/dist/providers/stripe.js +4 -3
- package/dist/providers/stripe.js.map +1 -1
- package/dist/validate.d.ts.map +1 -1
- package/dist/validate.js +97 -17
- package/dist/validate.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/documentation/cloudflare.md +37 -19
- package/documentation/code-mode.md +9 -9
- package/documentation/connectors.md +9 -7
- package/documentation/linear.md +6 -7
- package/documentation/meta-tools.md +56 -13
- package/documentation/mixpanel.md +6 -7
- package/documentation/stripe.md +12 -12
- package/ethos.md +2 -1
- package/package.json +1 -1
- package/src/catalog-service.ts +93 -29
- package/src/catalog.ts +71 -8
- package/src/connectors/api.ts +4 -4
- package/src/execute.ts +8 -7
- package/src/meta-tools.ts +1 -1
- package/src/providers/cloudflare.ts +275 -79
- package/src/providers/linear.ts +4 -3
- package/src/providers/mixpanel.ts +4 -3
- package/src/providers/stripe.ts +4 -3
- package/src/validate.ts +125 -20
- package/src/version.ts +1 -1
- package/templates/node/package.json +1 -1
package/src/validate.ts
CHANGED
|
@@ -57,6 +57,18 @@ interface ValidationUnit {
|
|
|
57
57
|
error: string;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
+
const CONTAINER_VALIDATION_KEYWORDS = new Set([
|
|
61
|
+
"properties",
|
|
62
|
+
"items",
|
|
63
|
+
"allOf",
|
|
64
|
+
"anyOf",
|
|
65
|
+
"oneOf",
|
|
66
|
+
"if",
|
|
67
|
+
"not",
|
|
68
|
+
"patternProperties",
|
|
69
|
+
"additionalProperties",
|
|
70
|
+
]);
|
|
71
|
+
|
|
60
72
|
function decodePointerPart(value: string): string {
|
|
61
73
|
return value.replaceAll("~1", "/").replaceAll("~0", "~");
|
|
62
74
|
}
|
|
@@ -81,6 +93,110 @@ function argumentPath(location: string): string {
|
|
|
81
93
|
return location.startsWith("#") ? location.slice(1) || "/" : "/";
|
|
82
94
|
}
|
|
83
95
|
|
|
96
|
+
function validationUnitKey(unit: ValidationUnit): string {
|
|
97
|
+
return JSON.stringify([
|
|
98
|
+
unit.keyword,
|
|
99
|
+
unit.keywordLocation,
|
|
100
|
+
unit.instanceLocation,
|
|
101
|
+
unit.error,
|
|
102
|
+
]);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function childPropertyName(
|
|
106
|
+
parentLocation: string,
|
|
107
|
+
childLocation: string,
|
|
108
|
+
): string | undefined {
|
|
109
|
+
const prefix = parentLocation === "#" ? "#/" : `${parentLocation}/`;
|
|
110
|
+
if (!childLocation.startsWith(prefix)) return undefined;
|
|
111
|
+
const encoded = childLocation.slice(prefix.length);
|
|
112
|
+
return !encoded.includes("/") ? decodePointerPart(encoded) : undefined;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
function schemaDeclaresProperty(schema: unknown, property: string): boolean {
|
|
116
|
+
if (schema === null || typeof schema !== "object" || Array.isArray(schema)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
const record = schema as Record<string, unknown>;
|
|
120
|
+
const properties = record.properties;
|
|
121
|
+
if (
|
|
122
|
+
properties !== null &&
|
|
123
|
+
typeof properties === "object" &&
|
|
124
|
+
!Array.isArray(properties) &&
|
|
125
|
+
Object.hasOwn(properties, property)
|
|
126
|
+
) {
|
|
127
|
+
return true;
|
|
128
|
+
}
|
|
129
|
+
const patterns = record.patternProperties;
|
|
130
|
+
if (
|
|
131
|
+
patterns === null ||
|
|
132
|
+
typeof patterns !== "object" ||
|
|
133
|
+
Array.isArray(patterns)
|
|
134
|
+
) {
|
|
135
|
+
return false;
|
|
136
|
+
}
|
|
137
|
+
for (const pattern of Object.keys(patterns)) {
|
|
138
|
+
try {
|
|
139
|
+
if (new RegExp(pattern).test(property)) return true;
|
|
140
|
+
} catch {
|
|
141
|
+
// The validator owns schema support. An unusable pattern cannot prove
|
|
142
|
+
// that this additional-properties branch is a duplicate.
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return false;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function isDuplicateAdditionalPropertiesBranch(
|
|
149
|
+
schema: JsonSchema,
|
|
150
|
+
units: ValidationUnit[],
|
|
151
|
+
index: number,
|
|
152
|
+
): boolean {
|
|
153
|
+
const unit = units[index];
|
|
154
|
+
const wrapper = units[index - 1];
|
|
155
|
+
if (
|
|
156
|
+
unit?.keyword !== "false" ||
|
|
157
|
+
wrapper?.keyword !== "additionalProperties" ||
|
|
158
|
+
!wrapper.keywordLocation.endsWith("/additionalProperties")
|
|
159
|
+
) {
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
const property = childPropertyName(
|
|
163
|
+
wrapper.instanceLocation,
|
|
164
|
+
unit.instanceLocation,
|
|
165
|
+
);
|
|
166
|
+
if (property === undefined) return false;
|
|
167
|
+
const parentSchemaLocation = wrapper.keywordLocation.slice(
|
|
168
|
+
0,
|
|
169
|
+
-"/additionalProperties".length,
|
|
170
|
+
);
|
|
171
|
+
return schemaDeclaresProperty(
|
|
172
|
+
pointerValue(schema, parentSchemaLocation || "#"),
|
|
173
|
+
property,
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function normalizedValidationUnits(
|
|
178
|
+
schema: JsonSchema,
|
|
179
|
+
units: ValidationUnit[],
|
|
180
|
+
): ValidationUnit[] {
|
|
181
|
+
const seen = new Set<string>();
|
|
182
|
+
return units.filter((unit, index) => {
|
|
183
|
+
if (CONTAINER_VALIDATION_KEYWORDS.has(unit.keyword)) return false;
|
|
184
|
+
if (isDuplicateAdditionalPropertiesBranch(schema, units, index)) {
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
const key = validationUnitKey(unit);
|
|
188
|
+
if (seen.has(key)) return false;
|
|
189
|
+
seen.add(key);
|
|
190
|
+
return true;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function agentFacingValidationError(unit: ValidationUnit): string {
|
|
195
|
+
return unit.keyword === "false"
|
|
196
|
+
? "Value is not allowed by the declared schema."
|
|
197
|
+
: unit.error;
|
|
198
|
+
}
|
|
199
|
+
|
|
84
200
|
function expectedType(schema: JsonSchema, unit: ValidationUnit): string | undefined {
|
|
85
201
|
if (unit.keyword === "type") {
|
|
86
202
|
const value = pointerValue(schema, unit.keywordLocation);
|
|
@@ -120,22 +236,8 @@ function validationDetails(
|
|
|
120
236
|
schema: JsonSchema,
|
|
121
237
|
units: ValidationUnit[],
|
|
122
238
|
): ArgumentValidationDetails {
|
|
123
|
-
const leafUnits = units.filter(
|
|
124
|
-
(unit) =>
|
|
125
|
-
![
|
|
126
|
-
"properties",
|
|
127
|
-
"items",
|
|
128
|
-
"allOf",
|
|
129
|
-
"anyOf",
|
|
130
|
-
"oneOf",
|
|
131
|
-
"if",
|
|
132
|
-
"not",
|
|
133
|
-
"patternProperties",
|
|
134
|
-
"additionalProperties",
|
|
135
|
-
].includes(unit.keyword),
|
|
136
|
-
);
|
|
137
239
|
const issues: ArgumentValidationIssue[] = [];
|
|
138
|
-
for (const unit of
|
|
240
|
+
for (const unit of units) {
|
|
139
241
|
const missing =
|
|
140
242
|
unit.keyword === "required"
|
|
141
243
|
? REQUIRED_PROPERTY_RE.exec(unit.error)?.[1]
|
|
@@ -246,15 +348,18 @@ export function validateToolInput(
|
|
|
246
348
|
return opts.failClosed ? unevaluableSchema(opts.address) : null;
|
|
247
349
|
}
|
|
248
350
|
if (result && !result.valid) {
|
|
249
|
-
const units = result.errors
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
.
|
|
351
|
+
const units = normalizedValidationUnits(schema, result.errors);
|
|
352
|
+
const nestedUnits = units.filter((unit) => unit.instanceLocation !== "#");
|
|
353
|
+
const detail = (nestedUnits.length > 0 ? nestedUnits : units)
|
|
354
|
+
.slice(0, MAX_ARGUMENT_VALIDATION_ISSUES)
|
|
355
|
+
.map((unit) =>
|
|
356
|
+
`${unit.instanceLocation}: ${agentFacingValidationError(unit)}`,
|
|
357
|
+
)
|
|
253
358
|
.join("; ");
|
|
254
359
|
return new ConnectorCallError(
|
|
255
360
|
"invalid_args",
|
|
256
361
|
`Invalid arguments for "${opts.address}": ${detail || "input does not match the tool's inputSchema"}`,
|
|
257
|
-
{ validation: validationDetails(schema,
|
|
362
|
+
{ validation: validationDetails(schema, units) },
|
|
258
363
|
);
|
|
259
364
|
}
|
|
260
365
|
return null;
|
package/src/version.ts
CHANGED