Skip to content

Discussion: Protocol Codec Architecture: Logical vs. Physical Separation in N+M IR Conversion #13

Description

@a-rookie-of-C-language

I have been following the TiyGate project closely, and our team is currently developing a project with a very similar vision called ferryllm.

It is exciting to see that TiyGate also leverages an Intermediate Representation (IR) approach, successfully reducing the complexity of multi-protocol translation from $N \times M$ to $N + M$. This aligns perfectly with the core design philosophy behind ferryllm.

However, we have taken slightly different paths when it comes to the concrete implementation of the codebase:

  • TiyGate uses Logical Separation: A single EndpointCodec (one comprehensive trait) encapsulates the entire inbound and outbound encoding/decoding logic.
  • ferryllm uses Physical Separation: It completely decouples entry (Client-to-IR) and adapter (IR-to-Provider) into distinct modules and single-direction traits.

To explore which model is better suited for long-term system evolution, or if there is a sweet spot between the two, I would love to open up a discussion here.

Comprehensive Comparison

Dimension Physical Separation (ferryllm approach) Logical Separation (TiyGate current)
File Count 2N (N protocols, independent entry/adapter) N (N protocols, single highly-cohesive file)
Module Boundaries Clear (strict separation of ingress/egress concerns) Blurred (both directions mixed within one type)
Trait Count 2 single-direction traits 1 bidirectional mega-trait
Registration Complexity Requires registering both entry and adapter Only requires a single codec registration
Code Reuse Needs explicit shared utility modules Natural reuse (shared type context)
Testing Granularity Fine-grained (unidirectional flows can be isolated) Coarse (tests must account for bidirectional logic)
Readability High (lower cognitive load, unidirectional focus) Lower (files grow significantly as protocols expand)
Maintainability Better when protocols differ drastically Better when protocols are highly similar
Extensibility More flexible (supports mix-and-match or single-direction) More compact (high protocol suite integrity)
Boilerplate High (more ceremony and setup code) Low (minimal overhead)

Discussion & Potential Hybrid Approach

While physical separation provides robust compile-time boundaries and isolated testability, it introduces boilerplate and registration overhead. On the flip side, logical separation keeps things compact but couples inbound and outbound concerns too tightly.

Could there be a third way—a Hybrid Approach?

For example:

  1. Physical Separation at the Trait Level: Split the logic into two separate traits—IngressCodec and EgressCodec—to guarantee compile-time boundaries and single-direction testing.
  2. Logical Cohesion at the Implementation Level: Allow the same struct (e.g., OpenAiCodec) to implement both traits within a single file. These can then be aggregated under a blanket EndpointCodec marker trait, preserving TiyGate's current elegant single-plugin registration mechanism (via inventory).

I would love to get your thoughts on the following:

  1. Has the current logical separation caused any maintenance pain points as protocols become more complex?
  2. Do we foresee scenarios where a protocol suite might only need a single direction (e.g., acting strictly as an ingress gateway without bridging to an underlying provider)?
  3. How do you view the evolution of this architecture going forward? Looking forward to the discussion!

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions