Enhance WebSocket session configuration by introducing an optional config.resolved event, which provides a public snapshot of the session's configuration. Update the API reference documentation to clarify the conditions under which this event is emitted and the details it includes. Modify session management to respect the new setting for emitting configuration details, ensuring sensitive information remains secure. Update tests to validate the new behavior and ensure compliance with the updated configuration schema.
This commit is contained in:
@@ -143,7 +143,9 @@ async def test_handle_session_start_requires_assistant_id_and_closes_transport()
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_session_start_applies_whitelisted_overrides_and_ignores_workflow():
|
||||
async def test_handle_session_start_applies_whitelisted_overrides_and_ignores_workflow(monkeypatch):
|
||||
monkeypatch.setattr("core.session.settings.ws_emit_config_resolved", False)
|
||||
|
||||
session = Session.__new__(Session)
|
||||
session.id = "sess_start_ok"
|
||||
session.ws_state = WsSessionState.WAIT_START
|
||||
@@ -175,7 +177,7 @@ async def test_handle_session_start_applies_whitelisted_overrides_and_ignores_wo
|
||||
return {
|
||||
"output": {"mode": "text"},
|
||||
"services": {"llm": {"provider": "openai", "model": "gpt-4o-mini"}},
|
||||
"tools": {"allowlist": []},
|
||||
"tools": {"allowlist": ["calculator"]},
|
||||
}
|
||||
|
||||
session.transport = _Transport()
|
||||
@@ -232,7 +234,94 @@ async def test_handle_session_start_applies_whitelisted_overrides_and_ignores_wo
|
||||
assert session.pipeline.applied["output"]["mode"] == "text"
|
||||
assert session.pipeline.applied["tools"] == [{"name": "calculator"}]
|
||||
assert not any(str(item.get("type", "")).startswith("workflow.") for item in events)
|
||||
assert not any(item.get("type") == "config.resolved" for item in events)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_handle_session_start_emits_config_resolved_when_enabled(monkeypatch):
|
||||
monkeypatch.setattr("core.session.settings.ws_emit_config_resolved", True)
|
||||
|
||||
session = Session.__new__(Session)
|
||||
session.id = "sess_start_emit_config"
|
||||
session.ws_state = WsSessionState.WAIT_START
|
||||
session.state = "created"
|
||||
session._assistant_id = "assistant_demo"
|
||||
session.current_track_id = Session.TRACK_CONTROL
|
||||
session._pipeline_started = False
|
||||
|
||||
class _Transport:
|
||||
async def close(self):
|
||||
return None
|
||||
|
||||
class _Pipeline:
|
||||
def __init__(self):
|
||||
self.started = False
|
||||
self.applied = {}
|
||||
self.conversation = type("Conversation", (), {"system_prompt": ""})()
|
||||
|
||||
async def start(self):
|
||||
self.started = True
|
||||
|
||||
async def emit_initial_greeting(self):
|
||||
return None
|
||||
|
||||
def apply_runtime_overrides(self, metadata):
|
||||
self.applied = dict(metadata)
|
||||
|
||||
def resolved_runtime_config(self):
|
||||
return {
|
||||
"output": {"mode": "text"},
|
||||
"services": {"llm": {"provider": "openai", "model": "gpt-4o-mini"}},
|
||||
"tools": {"allowlist": ["calculator"]},
|
||||
}
|
||||
|
||||
session.transport = _Transport()
|
||||
session.pipeline = _Pipeline()
|
||||
events = []
|
||||
|
||||
async def _start_history_bridge(_metadata):
|
||||
return None
|
||||
|
||||
async def _load_server_runtime_metadata(_assistant_id):
|
||||
return (
|
||||
{
|
||||
"assistantId": "assistant_demo",
|
||||
"configVersionId": "cfg_1",
|
||||
"systemPrompt": "Base prompt",
|
||||
"greeting": "Base greeting",
|
||||
"output": {"mode": "audio"},
|
||||
},
|
||||
None,
|
||||
)
|
||||
|
||||
async def _send_event(event):
|
||||
events.append(event)
|
||||
|
||||
async def _send_error(sender, message, code, **kwargs):
|
||||
raise AssertionError(f"Unexpected error: sender={sender} code={code} message={message} kwargs={kwargs}")
|
||||
|
||||
session._start_history_bridge = _start_history_bridge
|
||||
session._load_server_runtime_metadata = _load_server_runtime_metadata
|
||||
session._send_event = _send_event
|
||||
session._send_error = _send_error
|
||||
|
||||
await session._handle_session_start(
|
||||
SessionStartMessage(
|
||||
type="session.start",
|
||||
metadata={
|
||||
"channel": "web_debug",
|
||||
"overrides": {
|
||||
"output": {"mode": "text"},
|
||||
},
|
||||
},
|
||||
)
|
||||
)
|
||||
|
||||
config_event = next(item for item in events if item.get("type") == "config.resolved")
|
||||
assert config_event["config"]["appId"] == "assistant_demo"
|
||||
assert "appId" not in config_event["config"]
|
||||
assert "configVersionId" not in config_event["config"]
|
||||
assert "services" not in config_event["config"]
|
||||
assert config_event["config"]["channel"] == "web_debug"
|
||||
assert config_event["config"]["output"]["mode"] == "text"
|
||||
assert config_event["config"]["tools"]["enabled"] is True
|
||||
assert config_event["config"]["tools"]["count"] == 1
|
||||
|
||||
Reference in New Issue
Block a user