Kotlin sdk custom validation errors#1397
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a comprehensive streaming parser for A2UI (v0.8 and v0.9), including a base StreamingParser class and version-specific implementations. It also enhances schema management with new pruning capabilities for components, messages, and common types, and improves validation logic with more precise error reporting. Feedback includes suggestions to optimize regex compilation and object creation for better performance, handling potentially destructive path logic in v0.8, and adding checks for duplicate component IDs to ensure unambiguous error paths.
| val keyMatch = Regex("\"([^\"]+)\"\\s*:\\s*$").find(prefix) | ||
| if (keyMatch != null) { |
There was a problem hiding this comment.
In fixJson, a Regex object is created on each function call. Since this function might be called frequently in a streaming context, compiling this regular expression on each invocation can impact performance.
To optimize this, consider defining the regex as a private const val or in a companion object so it is compiled only once.
| val keyMatch = Regex("\"([^\"]+)\"\\s*:\\s*$").find(prefix) | |
| if (keyMatch != null) { | |
| val keyMatch = KEY_MATCH_REGEX.find(prefix) | |
| if (keyMatch != null) { |
| if (idx == -1) return null | ||
|
|
||
| val fragment = jsonBuffer.substring(idx) | ||
| val match = Regex("\"$key\"\\s*:\\s*\"([^\"]+)\"").find(fragment) |
There was a problem hiding this comment.
In getLatestValue, a Regex is created on every call. This function is called from sniffMetadata, which can be executed for every character in the JSON chunk, leading to potential performance overhead from repeated regex compilation.
Consider caching the compiled Regex instances, for example, in a map where the key is the string used to build the regex.
val regex = LATEST_VALUE_REGEX_CACHE.getOrPut(key) { Regex("\"$key\"\\s*:\\s*\"([^\"]+)\"") }
val match = regex.find(fragment)c6e2b7f to
c233336
Compare
| val duplicateIds = componentIds.groupingBy { it }.eachCount().filter { it.value > 1 }.keys | ||
| if (duplicateIds.isNotEmpty()) { | ||
| errors.add("$path.updateComponents: Duplicate component IDs found: ${duplicateIds.joinToString()}") | ||
| } else { |
There was a problem hiding this comment.
It skips other validations if duplicate component IDs are found. What about removing the else and letting the loop continue. This allows the caller to see all validation errors at once.
83ecf89 to
76b4691
Compare
Implements the full incremental A2UI v0.9 streaming parser suite in Kotlin, achieving SDK parity. Automatically incorporates critical subsequent fixes for robust real-time topology parsing and relative bindings. Port of Python SDK commit 8ba982a
Port of Python SDK commit 1ea689d
Implement coordinated component and message pruning via withPruning, propagating allowedMessages from A2uiSchemaManager down to Catalog. Add robust automated unit tests and enable full conformance verification. Port of Python SDK commit 0fd7240
Implements custom JSON-path validation error string construction for v0.9 payloads in Kotlin, matching Python exactly. Validates messages individually via sub-validators and iterates component arrays to construct precise path prefixes. Port of Python SDK commit 15ee789 � Conflicts: � agent_sdks/kotlin/src/main/kotlin/com/google/a2ui/core/parser/StreamingParser.kt � agent_sdks/kotlin/src/main/kotlin/com/google/a2ui/core/schema/Validator.kt
76b4691 to
7c5e104
Compare
Description
Implements custom JSON-path validation error string construction for v0.9 payloads in Kotlin, matching Python exactly. Validates messages individually via sub-validators and iterates component arrays to construct precise path prefixes.
Port of Python SDK commit 15ee789
Pre-launch Checklist
If you need help, consider asking for advice on the discussion board.