
    `gj
                    \    d Z ddlmZ ddlZddlmZmZ dZ ed       G d d	             Zy)
u  CapabilityDescriptor — the relay handshake payload. EXPERIMENTAL.

The connector hands a ``CapabilityDescriptor`` to the gateway's ``RelayAdapter``
at handshake time; it tells the adapter which platform it is fronting and which
capabilities to advertise to the ``GatewayStreamConsumer`` (char limit,
draft-streaming, edit/threading support, markdown dialect, length unit). It is
the linchpin of the generalization: one gateway adapter serves Discord,
Telegram, Matrix, Signal, ... without per-platform branching.

EXPERIMENTAL: this schema MAY CHANGE without a deprecation cycle until at least
two real Class-1 platforms have validated it. Evolution during the experimental
phase is additive-only, gated by ``contract_version`` (see
docs/relay-connector-contract.md).

Field origins (most are a wire-serializable projection of ``PlatformEntry`` plus
the per-instance capability methods on ``BasePlatformAdapter``):

- ``max_message_length`` -> ``PlatformEntry.max_message_length`` / adapter
  ``MAX_MESSAGE_LENGTH`` attribute (read by stream_consumer).
- ``len_unit``           -> selects which ``message_len_fn`` the adapter installs
  ("chars" = builtin len; "utf16" = Telegram-style UTF-16 code-unit counting).
- ``supports_draft_streaming`` -> adapter ``supports_draft_streaming()`` probe.
- ``supports_edit``      -> whether edit-based streaming is possible (Discord/
  Telegram yes; Signal/SMS no -> consumer degrades to one-message-per-segment).
- ``supports_threads``   -> ``create_handoff_thread`` capability flag.
- ``markdown_dialect``   -> presentation hint (e.g. "markdown_v2", "discord").
- ``emoji`` / ``platform_hint`` / ``pii_safe`` -> ``PlatformEntry`` fields of the
  same name.
    )annotationsN)asdict	dataclass   T)frozenc                      e Zd ZU dZded<   ded<   ded<   ded<   ded	<   ded
<   ded<   ded<   ded<   dZded<   dZded<   dZded<   dZded<   ddZ	e
dd       Ze
dddddd	 	 	 	 	 	 	 	 	 	 	 dd       Zy) CapabilityDescriptoru   Immutable capability descriptor negotiated at relay handshake.

    Frozen so a descriptor cannot be mutated after handshake — the adapter
    advertises a fixed capability profile for the life of the connection.
    intcontract_versionstrplatformlabelmax_message_lengthboolsupports_draft_streamingsupports_editsupports_threadsmarkdown_dialectlen_unit   🔌emoji platform_hintFpii_safesupports_contextc                D    t        j                  t        |       dd      S )zCSerialize to a compact, stable JSON string for the handshake frame.TF)	sort_keysensure_ascii)jsondumpsr   )selfs    K/root/.hermes/venv/lib/python3.12/site-packages/gateway/relay/descriptor.pyto_jsonzCapabilityDescriptor.to_jsonD   s    zz&,$UKK    c                >   t        j                  |      }| j                  D ch c]  }| }}|j                         D ci c]  \  }}||v s|| }}}d|v r	 t	        |d         dk  rd|d<    | di |S c c}w c c}}w # t
        t        f$ r d|d<   Y )w xY w)zDeserialize from a handshake JSON string.

        Unknown keys are ignored (forward-compat: a newer connector may send
        fields this gateway does not know yet); missing optional keys fall back
        to dataclass defaults.
        r   r       )r   loads__dataclass_fields__itemsr
   	TypeError
ValueError)clsdatarawfknownkvfiltereds           r"   	from_jsonzCapabilityDescriptor.from_jsonH   s     jj445q55%(YY[?TQAJAqD??  8+6x 456!;59H12 X 6? z* 615-.6s#   	A:A?A?B BBcharsTplain)r   r   r   r   r   c                   t        |dd      xs d} | t        |j                  |j                  ||||||t        |dd      t        |dd      t        |dd	      
      S )u:  Project a ``gateway.platform_registry.PlatformEntry`` into a descriptor.

        Demonstrates the descriptor is a *subset/projection* of what
        ``PlatformEntry`` already encodes, not a parallel concept: ``label``,
        ``max_message_length``, ``emoji``, ``platform_hint``, ``pii_safe`` and
        the platform name come straight off the entry. The runtime capability
        bits that ``PlatformEntry`` does NOT encode (length unit, draft/edit/
        thread/markdown behavior) are supplied by the caller — in production
        the connector fills these from the live adapter's capability methods.

        ``max_message_length`` of 0 on a ``PlatformEntry`` means "no limit";
        we map that to the stream_consumer default of 4096 so the descriptor
        always carries a concrete chunking bound.
        r   r   r&   r   r   r   r   r   F)r   r   r   r   r   r   r   r   r   r   r   r   )getattrCONTRACT_VERSIONnamer   )r-   entryr   r   r   r   r   max_lens           r"   from_platform_entryz(CapabilityDescriptor.from_platform_entryb   sl    2 %!5q9AT-ZZ++&%='--%,7!%"=UJ6
 	
r$   N)returnr   )r.   r   r?   'CapabilityDescriptor')r   r   r   r   r   r   r   r   r   r   r?   r@   )__name__
__module____qualname____doc____annotations__r   r   r   r   r#   classmethodr5   r>   r'   r$   r"   r	   r	   )   s     MJ""ME3M3Hd #d"L  2 
  )."!& '&
 	&

 #'&
 &
 &
 &
 
 &
 &
r$   r	   )	rD   
__future__r   r   dataclassesr   r   r:   r	   r'   r$   r"   <module>rI      s>   < #  )   $_
 _
 _
r$   