Skip to content

docs(proposals): add What?/Why? for A2A task route capture parse comp…#396

Open
mkoushni wants to merge 9 commits into
praxis-proxy:mainfrom
mkoushni:docs/353-a2a-task-route-capture-parse-complexity
Open

docs(proposals): add What?/Why? for A2A task route capture parse comp…#396
mkoushni wants to merge 9 commits into
praxis-proxy:mainfrom
mkoushni:docs/353-a2a-task-route-capture-parse-complexity

Conversation

@mkoushni

Copy link
Copy Markdown
Contributor

Summary

try_capture_from_buffer in filters/src/agentic/a2a/mod.rs (the
non-streaming A2A task-route capture path) hex-decodes and attempts a
full serde_json::from_slice parse over the entire accumulated
response buffer
on every on_response_body chunk, discarding the
result whenever the JSON is still incomplete. For a body delivered in
k chunks, this repeats full decode+parse work over an ever-growing
buffer on every chunk, producing O(n²) total work in response body
bytes rather than O(n) — see #353.

This PR adds the proposal's What?/Why? sections per the
docs/proposals/template.md convention. Per the template note, the
How? section is intentionally omitted here and will follow in a
separate PR once the proposal direction is agreed.

What's in this PR

  • New proposal: docs/proposals/00353_a2a-task-route-capture-parse-complexity.md
  • Describes bounding the per-chunk capture cost to O(chunk) via an
    incremental, string-aware brace/bracket depth scan, so the
    expensive hex-decode + JSON parse is only attempted once the buffer
    plausibly holds a complete, balanced JSON value.
  • Explicitly scoped to the non-streaming capture path only — the
    SSE capture path (process_sse_response_chunk) already scans
    incrementally and is unaffected.
  • Preserves the existing opportunistic, pre-EOS capture requirement
    (a route must be captured as soon as the JSON body is complete,
    without waiting for end_of_stream, since Pingora may not deliver
    a separate EOS callback after the final data chunk).
  • Non-goals: no change to the hex-encoding scheme used for multibyte
    UTF-8 chunk-boundary safety, no change to the SSE scanner, and no
    overlap with fix(a2a): streaming methods with non-SSE response skip task route capture #352 (handled separately).

Test plan

  • make lint passes (clippy, fmt-check, separator/filter-docs lints)
  • No code changes in this PR — documentation only

Relates to #353

…lexity

try_capture_from_buffer in the A2A filter hex-decodes and JSON-parses
the entire accumulated response buffer on every on_response_body
chunk, producing O(n^2) work in total response body bytes. Add the
proposal's What?/Why? sections per the docs/proposals template; the
How? section will follow in a separate PR once direction is agreed.

Relates to praxis-proxy#353

Signed-off-by: mkoushni <mkoushni@redhat.com>

@aslakknutsen aslakknutsen left a comment

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.

Notation fix (What?/Why?): Current cost is Θ(n·k) for body size n and chunk count k, not “O(n²) in the number of chunks.” O(n²) only holds when k = Θ(n) (e.g. 1-byte chunks). Align the What?

Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md Outdated
Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md Outdated
Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md
Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md Outdated
Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md Outdated
The What?/Why? sections and graduation criteria described the current
try_capture_from_buffer cost as flatly "O(n²) in the number of
chunks," which only holds when chunk count k scales with body size n
(e.g. 1-byte chunks). State the general cost as Θ(n·k) for body size n
and chunk count k, calling out Θ(n²) as the fine-grained-chunking
special case.

Also drop the placeholder discussion field: this proposal originates
from a bot-flagged issue (praxis-proxy#353) with no prior discussion thread to
link.

Addresses review from @aslakknutsen on praxis-proxy#396.

Signed-off-by: mkoushni <mkoushni@redhat.com>
@praxis-bot-app

Copy link
Copy Markdown

Proposal validation failed:

  • docs/proposals/00353_a2a-task-route-capture-parse-complexity.md: missing discussion field in frontmatter
    See proposal process for requirements.

@mkoushni
mkoushni requested a review from aslakknutsen July 21, 2026 11:14
mkoushni added 4 commits July 21, 2026 14:14
Replace shaneutt/nerdalert with aslakknutsen, who is the actual
reviewer engaged on this proposal (praxis-proxy#396).

Signed-off-by: mkoushni <mkoushni@redhat.com>
Removing the discussion field per review feedback broke the
proposal-check workflow, which requires a non-empty discussion field
per docs/proposals.md ("CI will close PRs that: Are missing a
discussion or issue link"). This proposal has no separate GitHub
Discussion thread (it originates from a bot-flagged issue), so point
discussion at this PR's own conversation instead, which is where the
What?/Why? discussion is actually happening.

Signed-off-by: mkoushni <mkoushni@redhat.com>

@praxis-bot praxis-bot left a comment

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.

Proposal Review: A2A Task Route Capture Parse Complexity

Clean, well-structured proposal that correctly follows the template convention (What?/Why? only, How? deferred to a follow-up PR). The technical analysis of the O(n²) complexity in try_capture_from_buffer is sound, the scoping to the non-streaming capture path is appropriate, and the goals/non-goals are clearly delineated.

One formatting nit: several prose lines in the body text exceed the 80-character markdown wrap limit (up to 192 chars on the worst offender). See inline comment.

Severity Count
Medium 1

🤖 Reviewed by praxis-bot

Comment thread docs/proposals/00353_a2a-task-route-capture-parse-complexity.md
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants