연결과 인증¶
클라이언트는 /sohri로 WebSocket 핸드셰이크를 수행합니다. credential은 다음 순서로 찾습니다.
Authorization: Bearer <credential>Sec-WebSocket-Protocol: sohri.apikey, <api-key>또는sohri.token, <token>?api_key=<credential>또는?token=<credential>
형식이 sr_live_/sr_test_이면 workspace API key, JWT 형태이면 app-backend가 발급한
Ed25519 세션 에페메랄 토큰으로 분기합니다. API key는 workspace, key ID, key type을
스탬핑하고, 토큰은 aud=sohri-realtime, iss=sohri-app-backend, exp, sub,
workspaceId를 검증해 workspace와 member ID를 스탬핑합니다.
인증 모드¶
app.auth.mode |
credential 없음 | 유효 credential | 무효 credential |
|---|---|---|---|
disabled |
통과 | 검증 없이 통과 | 검증 없이 통과 |
permissive |
미귀속으로 통과 | 검증·귀속 | 거절 |
enforced |
401 |
검증·귀속 | 거절 |
API key 미존재·폐기·IP 불일치는 403입니다. 토큰의 형식 오류·만료·공개키 미설정은 401,
서명 또는 필수 클레임 불일치는 403입니다. 브라우저 서브프로토콜 방식을 쓰면 서버가 marker를
에코해야 핸드셰이크가 성립합니다.
연결과 엔진 확정 순서¶
sequenceDiagram
participant C as Client/Gateway
participant A as Handshake Auth
participant W as Connection Handler
participant DB as PostgreSQL
participant R as Engine Router
participant O as OpenAI Realtime
participant E as EPD
C->>A: GET /sohri Upgrade + credential
A->>A: 채널 추출 → 형식 분기 → 검증
alt 인증 거절
A-->>C: HTTP 401 또는 403
else 인증 승인
A->>W: workspace/member/apiKey attributes
W->>W: IP rate limit · 세션 상한 등록
W->>DB: dialog 생성(started_at)
DB-->>W: dialogId
W-->>C: connection_established
end
opt PCM보다 먼저 명시 선택
C->>R: conversation_session_update(engine)
alt engine = openai_realtime
R->>O: upstream 연결 + session.update
O-->>R: session.updated
else engine = sohri
R->>R: SOHRI 선택 기록
end
R-->>C: conversation_session_updated
end
alt 명시 선택 없이 첫 PCM 도착
C->>R: Binary PCM
R->>R: SOHRI를 원자적으로 선택·잠금
R->>E: 첫 PCM에서 EPD 지연 연결 후 전송
else 선택 후 PCM 도착
C->>R: Binary PCM
R->>R: 선택된 엔진으로 전달
end
C->>R: 다른 엔진으로 재설정
R-->>C: 409 CONVERSATION_ENGINE_INVALID
엔진은 첫 conversation_session_update 또는 첫 PCM으로 잠깁니다. 같은 OpenAI 엔진으로 다시
설정하면 사용자 컨텍스트와 instructions를 session.update로 갱신할 수 있지만, 다른 엔진으로
바꿀 수는 없습니다. 최초 OpenAI 설정이 실패하면 선택 기록을 제거하므로 유효한 설정으로 다시
시도할 수 있습니다.
연결 ACK는 엔진 준비 ACK가 아닙니다
connection_established는 WebSocket 세션과 대화 행이 준비됐다는 뜻입니다.
OpenAI Realtime 준비 완료는 별도의 conversation_session_updated로 확인해야 합니다.
연결 쿼리¶
연결 시 EPD(minSpeech, endSilence, epdTimeout), 연속 입력(continuousAudio), TTS 출력
샘플레이트(ttsSampleRate), TTS 스트리밍(ttsStream=v1)을 협상할 수 있습니다. 세부 값은
설정 참조를 참고하세요.