@feniix/bridgekit 0.8.0 → 0.8.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 +13 -1
- package/dist/src/core/execute-tool.js +35 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,19 @@ All notable changes to `@feniix/bridgekit` are documented here. The format
|
|
|
4
4
|
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
|
|
5
5
|
adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
|
-
## [0.8.
|
|
7
|
+
## [0.8.1] - Unreleased
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- Union-of-objects validation no longer surfaces phantom missing-required-
|
|
12
|
+
property entries for every branch. When TypeBox emits an `anyOf`/`oneOf`
|
|
13
|
+
error at a path, sibling `required`/`additionalProperties` entries at the
|
|
14
|
+
same path are now suppressed so consumers see only the union summary.
|
|
15
|
+
`const`/`enum` discriminator errors at deeper paths are kept (they're
|
|
16
|
+
signal about which branch was intended).
|
|
17
|
+
Resolves [#35](https://github.com/feniix/bridgekit/issues/35).
|
|
18
|
+
|
|
19
|
+
## [0.8.0] - 2026-05-26
|
|
8
20
|
|
|
9
21
|
### Breaking
|
|
10
22
|
|
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import { Check, Errors } from "typebox/value";
|
|
2
2
|
const ROOT_FIELD = "(root)";
|
|
3
|
+
function suppressSiblingErrorsUnderUnion(errors) {
|
|
4
|
+
// For unions of objects, TypeBox emits per-branch `required` /
|
|
5
|
+
// `additionalProperties` errors at the union's path. The user only needs
|
|
6
|
+
// to satisfy ONE branch, so those entries are phantoms; the `anyOf` /
|
|
7
|
+
// `oneOf` summary at the same path is the real signal.
|
|
8
|
+
//
|
|
9
|
+
// `const` / `enum` errors at the same path survive — they carry real
|
|
10
|
+
// discriminator info about which branch was intended.
|
|
11
|
+
//
|
|
12
|
+
// Known trade-off (#38): discriminated unions where the user picks a
|
|
13
|
+
// branch correctly but forgets that branch's required props also lose
|
|
14
|
+
// the "you picked tag=X and forgot Y" hint. Keyword-aware branch
|
|
15
|
+
// matching is the follow-up.
|
|
16
|
+
const unionPaths = new Set();
|
|
17
|
+
for (const error of errors) {
|
|
18
|
+
if (error.keyword === "anyOf" || error.keyword === "oneOf") {
|
|
19
|
+
unionPaths.add(error.instancePath);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
if (unionPaths.size === 0)
|
|
23
|
+
return errors;
|
|
24
|
+
return errors.filter((error) => {
|
|
25
|
+
if (!unionPaths.has(error.instancePath))
|
|
26
|
+
return true;
|
|
27
|
+
return error.keyword !== "required" && error.keyword !== "additionalProperties";
|
|
28
|
+
});
|
|
29
|
+
}
|
|
3
30
|
function expandTypeBoxError(error) {
|
|
4
31
|
// Read offending property names from TypeBox's structured `params` rather
|
|
5
32
|
// than parsing the message string. Two payoffs: locale independence (the
|
|
@@ -32,11 +59,15 @@ export function validatePortableToolArgs(tool, args) {
|
|
|
32
59
|
return { ok: true };
|
|
33
60
|
}
|
|
34
61
|
// TypeBox can emit multiple errors per offending field (e.g. union/anyOf
|
|
35
|
-
// mismatches fire one error per failed branch).
|
|
36
|
-
//
|
|
37
|
-
//
|
|
62
|
+
// mismatches fire one error per failed branch). First, when an anyOf/oneOf
|
|
63
|
+
// error fires at a path, drop sibling `required`/`additionalProperties`
|
|
64
|
+
// errors at the same path — they're phantoms (the consumer only needs to
|
|
65
|
+
// satisfy ONE branch, not all of them). Then dedupe the survivors by
|
|
66
|
+
// (field, message) using JSON.stringify so the key can't collide regardless
|
|
67
|
+
// of what characters field or message contain.
|
|
68
|
+
const rawErrors = suppressSiblingErrorsUnderUnion([...Errors(tool.parameters, args)]);
|
|
38
69
|
const seen = new Set();
|
|
39
|
-
const errors =
|
|
70
|
+
const errors = rawErrors
|
|
40
71
|
.flatMap((error) => expandTypeBoxError(error))
|
|
41
72
|
.filter(({ field, message }) => {
|
|
42
73
|
const key = JSON.stringify([field, message]);
|