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
Source code in autogen/beta/network/adapters/conversation.py
| def initial_state(self, metadata: ChannelMetadata) -> ConversationState:
return ConversationState()
|
fold
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(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(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,
)
|