Skip to content

ConversationAdapter

autogen.beta.network.adapters.conversation.ConversationAdapter #

ConversationAdapter()

Bidirectional multi-turn 1+1 channel.

Knobs: none. Participants: exactly 2 (initiator + respondent). Default view: :class:WindowedSummary(recent_n=10) — bounded prompt size at any turn count.

Source code in autogen/beta/network/adapters/conversation.py
def __init__(self) -> None:
    self._say_tool_cache: dict[str, object] = {}
    self.manifest = ChannelManifest(
        type=CONVERSATION_TYPE,
        version=1,
        participants=ParticipantSchema(
            min=2,
            max=2,
            roles=[ParticipantRole.INITIATOR.value, ParticipantRole.RESPONDENT.value],
        ),
        knobs_schema={},
        default_view_policy=WindowedSummary.name,
        expectations=[
            Expectation(
                name="max_silence",
                on_violation="audit",
                params={"seconds": 3600},
            ),
        ],
    )

manifest instance-attribute #

manifest = ChannelManifest(type=CONVERSATION_TYPE, version=1, participants=ParticipantSchema(min=2, max=2, roles=[INITIATOR.value, RESPONDENT.value]), knobs_schema={}, default_view_policy=name, expectations=[Expectation(name='max_silence', on_violation='audit', params={'seconds': 3600})])

initial_state #

initial_state(metadata)
Source code in autogen/beta/network/adapters/conversation.py
def initial_state(self, metadata: ChannelMetadata) -> ConversationState:
    return ConversationState()

fold #

fold(envelope, state)
Source code in autogen/beta/network/adapters/conversation.py
def fold(self, envelope: Envelope, state: ConversationState) -> ConversationState:
    if _is_channel_protocol_event(envelope) or _is_task_event(envelope):
        return state
    if envelope.event_type != EV_TEXT:
        return state
    return ConversationState(
        turn_count=state.turn_count + 1,
        last_speaker_id=envelope.sender_id,
        last_envelope_id=envelope.envelope_id,
    )

validate_create #

validate_create(metadata)
Source code in autogen/beta/network/adapters/conversation.py
def validate_create(self, metadata: ChannelMetadata) -> None:
    roles = {p.role for p in metadata.participants}
    if ParticipantRole.INITIATOR not in roles:
        raise ProtocolError("conversation requires exactly one initiator")
    if ParticipantRole.RESPONDENT not in roles:
        raise ProtocolError("conversation requires exactly one respondent")
    if len(metadata.participants) != 2:
        raise ProtocolError(f"conversation requires exactly 2 participants, got {len(metadata.participants)}")

validate_send #

validate_send(metadata, envelope, state)
Source code in autogen/beta/network/adapters/conversation.py
def validate_send(
    self,
    metadata: ChannelMetadata,
    envelope: Envelope,
    state: ConversationState,
) -> None:
    if _is_channel_protocol_event(envelope) or _is_task_event(envelope):
        return
    if envelope.event_type != EV_TEXT:
        # Unknown event types accepted as informational data — same
        # convention as consulting.
        return
    participant_ids = {p.agent_id for p in metadata.participants}
    if envelope.sender_id not in participant_ids:
        raise ProtocolError(
            f"conversation channel {metadata.channel_id!r} only accepts "
            f"sends from participants, got {envelope.sender_id!r}"
        )

on_accepted #

on_accepted(metadata, envelope, state)
Source code in autogen/beta/network/adapters/conversation.py
def on_accepted(
    self,
    metadata: ChannelMetadata,
    envelope: Envelope,
    state: ConversationState,
) -> AdapterResult:
    # Conversations end via explicit ``Hub.close_channel`` or TTL
    # — never via adapter-initiated transitions on accepted content.
    return AdapterResult()

expected_next #

expected_next(metadata, state)
Source code in autogen/beta/network/adapters/conversation.py
def expected_next(
    self,
    metadata: ChannelMetadata,
    state: ConversationState,
) -> ExpectedTurn | None:
    # Conversation has no turn ordering — any participant may
    # speak at any time, so there is no expected next speaker.
    return default_expected_next(metadata, state)

default_view_policy #

default_view_policy(metadata, participant_id)
Source code in autogen/beta/network/adapters/conversation.py
def default_view_policy(
    self,
    metadata: ChannelMetadata,
    participant_id: str,
) -> ViewPolicy:
    return WindowedSummary(recent_n=_DEFAULT_RECENT_N)

extract_turn_input #

extract_turn_input(envelope)
Source code in autogen/beta/network/adapters/conversation.py
def extract_turn_input(self, envelope):
    return default_extract_turn_input(envelope)

build_round_envelope #

build_round_envelope(metadata, sender_id, reply, events, state, hub)
Source code in autogen/beta/network/adapters/conversation.py
def build_round_envelope(self, metadata, sender_id, reply, events, state, hub):
    return default_build_round_envelope(metadata, sender_id, reply, events, state, hub)

render_envelope #

render_envelope(envelope)
Source code in autogen/beta/network/adapters/conversation.py
def render_envelope(self, envelope):
    return default_render_envelope(envelope)

tools_for #

tools_for(client, metadata, state, participant_id)

Conversation has no turn order — both participants always see say. Tool resolution is memoized per-client.

Source code in autogen/beta/network/adapters/conversation.py
def tools_for(self, client, metadata, state, participant_id):
    """Conversation has no turn order — both participants always
    see ``say``. Tool resolution is memoized per-client.
    """
    return [self._cached_say_tool(client)]

build_text_envelope #

build_text_envelope(channel_id, sender_id, text, *, audience=None, causation_id=None)
Source code in autogen/beta/network/adapters/conversation.py
def build_text_envelope(self, channel_id, sender_id, text, *, audience=None, causation_id=None):
    return default_build_text_envelope(channel_id, sender_id, text, audience=audience, causation_id=causation_id)

build_packet_envelope #

build_packet_envelope(channel_id, sender_id, body, *, handoff=None, context_set=None, audience=None, causation_id=None)
Source code in autogen/beta/network/adapters/conversation.py
def build_packet_envelope(
    self,
    channel_id,
    sender_id,
    body,
    *,
    handoff=None,
    context_set=None,
    audience=None,
    causation_id=None,
):
    return default_build_packet_envelope(
        channel_id,
        sender_id,
        body,
        handoff=handoff,
        context_set=context_set,
        audience=audience,
        causation_id=causation_id,
    )