Skip to content

Kotlin sdk custom validation errors#1397

Open
jgindin wants to merge 4 commits into
google:mainfrom
jgindin:kotlin-sdk-custom-validation-errors
Open

Kotlin sdk custom validation errors#1397
jgindin wants to merge 4 commits into
google:mainfrom
jgindin:kotlin-sdk-custom-validation-errors

Conversation

@jgindin
Copy link
Copy Markdown
Collaborator

@jgindin jgindin commented May 11, 2026

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.

@jgindin jgindin requested a review from nan-yu May 11, 2026 16:25
@jgindin jgindin self-assigned this May 11, 2026
@github-project-automation github-project-automation Bot moved this to Todo in A2UI May 11, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread agent_sdks/kotlin/src/main/kotlin/com/google/a2ui/core/parser/StreamingParser.kt Outdated
Comment on lines +180 to +181
val keyMatch = Regex("\"([^\"]+)\"\\s*:\\s*$").find(prefix)
if (keyMatch != null) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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.

Suggested change
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)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

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)

Comment thread agent_sdks/kotlin/src/main/kotlin/com/google/a2ui/core/parser/StreamingParser.kt Outdated
@jgindin jgindin force-pushed the kotlin-sdk-custom-validation-errors branch 3 times, most recently from c6e2b7f to c233336 Compare May 12, 2026 15:51
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 {
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@jgindin jgindin force-pushed the kotlin-sdk-custom-validation-errors branch 5 times, most recently from 83ecf89 to 76b4691 Compare May 15, 2026 20:37
jgindin added 4 commits May 15, 2026 16:39
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
@jgindin jgindin force-pushed the kotlin-sdk-custom-validation-errors branch from 76b4691 to 7c5e104 Compare May 15, 2026 20:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

2 participants