VIRGO

채팅 앱을 Virgo에 연결하기

작성 기준
50a34893e3086a6012fd136d5e4a492a9066c5bc
제품 소스
channel-access/README.md, runtime/install-main.ts, cli/management-cli.ts, adapters/discovery.ts, runtime/agent-management.ts

이 가이드는 고정된 문서를 그대로 옮긴 것이 아니라 이 사이트가 직접 쓴 글입니다. 위의 제품 커밋을 기준으로 작성했으며, 인용한 모든 제품 경로가 그 커밋에 실제로 있는지 확인했습니다.

provider 포털 단계는 각 provider의 공식 문서를 따릅니다. 문서 끝에 링크가 있으며, provider가 소유한 부분은 그 문서를 따르세요.

채팅 앱을 Virgo에 연결하기

Virgo의 팀은 사람들이 이미 대화하는 곳에서 답할 수 있습니다. 채팅 adapter는 Discord, Microsoft Teams, Telegram 중 하나의 채팅 provider를 이미 운영 중인 Virgo 설치본에 연결합니다. 그러면 사람은 자기 채팅 클라이언트에서 Seat을 부르고, 같은 대화·thread·메시지로 답을 받습니다.

이 페이지는 채팅 adapter가 무엇이고 무엇이 필요한지, 그리고 현재 릴리스가 여러분을 어디까지 데려다주는지를 설명합니다. 이어지는 세 개의 provider 가이드가 각각 하나씩 다룹니다.

adapter라고 불리는 두 가지

agent provider adapter(Claude, Codex)는 agent가 실제로 일하는 provider 대화에 Seat을 붙입니다. 사람용 채팅 adapter(Discord, Teams, Telegram)는 사람을 들여보냅니다. 사용자, 채널, thread, 회신이 그것입니다.

둘 다 Hub에서 끝나며, 그게 핵심입니다. adapter는 자기 provider의 메커니즘을 소유합니다. gateway, webhook, polling, 첨부 전송, 반응 상태가 그렇습니다. Hub는 provider마다 달라져서는 안 되는 것을 쥡니다. 발신자가 누구인지, 무엇을 요청할 수 있는지, 어느 Seat이 받는지, 그리고 무엇이 전달되었는지의 지속 기록입니다.

설치본 하나면 되고, Seat마다 봇이 필요하지 않습니다

채팅 adapter는 Virgo 옆에 따로 설치하는 제품이 아니며, Seat마다 봇을 추가하지도 않습니다. 설정된 봇 하나가 여러분이 허용한 목적지들을 담당하고, 받아들여진 메시지를 어느 Seat이 받을지는 Hub가 정합니다. provider의 표시 이름과 사용자명은 진단용일 뿐이며, 정책을 고르거나 접근 권한을 주지 않습니다.

이미 있는 설치본에 추가하기

이 자리는 예전에 이 문서의 공백이었습니다. 지금은 지원되는 경로가 있습니다. adapter add, adapter list, adapter remove가 이미 존재하는 설치본의 adapter 목록을 설치본을 갈아치우지 않고 바꿉니다.

adapter add --file /absolute/path/to/descriptor.json
adapter list
adapter remove <id>

설정은 파일로 전달하며 경로는 절대 경로여야 합니다. 그 설정은 provider 모듈이 직접 해독하는 입력이므로, 여기에 설정마다 플래그를 두는 표면은 없습니다.

adapter add는 받아들이는 것보다 거부하는 것이 많고, 그것이 핵심입니다. 서술자는 id를 반드시 지정해야 하고, 이미 목록에 있는 id는 갱신이 아니라 충돌입니다. 교체했다면 기존 항목이 담고 있던 것을 조용히 잃었을 것이기 때문입니다. 새 항목만 준비되므로 옆 adapter가 저장해 둔 출력이 다시 쓰이는 일은 없습니다. 그다음 목록 전체를 부팅이 검증하는 방식 그대로, id와 session과 Seat의 고유성까지 포함해 검증합니다. 그래서 추가가 시작되지 않을 구성을 남길 수 없습니다.

자격 증명은 같은 작업 안에서 등록됩니다. 서술자는 reference와 그 source를 지정하는 credentialBinding을 담을 수 있고, 그 참조는 adapter와 함께 설치 설정에 기록됩니다. 절반만 성공할 수 있는 두 번째 단계가 아닙니다. 이미 있는 참조를 다른 source로 돌리는 것은 거부됩니다. 그것을 읽고 있던 무언가를 조용히 다른 곳으로 돌리는 일이기 때문입니다. 모듈 자신의 설정이 한 번도 지칭하지 않는 binding도 거부됩니다. 아무도 읽지 않을 것이기 때문입니다.

adapter list는 등록된 내용을 되읽습니다. 각 항목의 id, 종류, session, Seat, 대화 목적지, 그 항목이 읽는 자격 증명 참조, 그리고 항목이 유효하지 않다면 모듈 자신의 지적입니다. 참조의 이름만 보여 주며, 비밀이 어디에 있는지도 그 바이트도 보여 주지 않습니다.

adapter remove는 id를 받고, 설치본에 남은 무엇도 더는 지칭하지 않는 자격 증명 참조를 함께 정리합니다.

새 adapter는 다음 Host 시작에서 활성화됩니다. 동작 중인 Host는 자신이 부팅할 때 가지고 있던 adapter를 그대로 들고 있으며, 다시 적재하는 경로는 없습니다. 네이티브 agent 세션은 의도적으로 건드리지 않습니다. 채팅 하나를 추가하려고 그것들을 재시작하면 바로 이 작업이 지키려는 세션을 흔들게 되기 때문입니다.

채팅을 추가하려고 Hub를 다시 설치하지 마세요. 경로가 없던 때에도 맞는 말이었고, 경로가 생긴 지금도 맞습니다. 다시 설치하는 것은 adapter add가 제자리에서 기록하는 구성 항목 하나를 얻으려고 동작 중인 설치본을 갈아치우는 일입니다.

누가 팀에 말을 걸 수 있는가

인증된 provider 이벤트는 Hub에 닿기 전에 모두 공용 접근 게이트를 지납니다. 세 가지 모드가 있습니다.

모드의미
open설정되고 인증된 채널의 모든 발신자를 받아들입니다.
restricted명시적 허용 목록에 있는 발신자만 받아들입니다.
approval새 발신자의 첫 메시지를 보관해 두고 관리자가 결정합니다.

기본값은 provider마다 다릅니다. Discord와 Telegram은 둘 다 approval이 기본이고, Teams는 인증된 테넌트·대화 binding 안에서 open이 기본입니다.

approval이 기본인 provider는 서술자에 두 가지가 있어야 하며, 없으면 설치가 거부합니다. 관리자 principal 최소 한 명, 그리고 대기 중인 요청을 공지할 경로입니다. Discord는 accessNotificationRoute, Telegram은 accessNotificationChatId입니다.

관리자는 정확히 정해진 예약 메시지로 대기 중인 요청을 결정합니다.

/virgo-access approve <requestId>
/virgo-access deny <requestId>

Teams 관리자는 대신 타입이 정해진 카드 데이터 { "kind": "virgo.channel_access.decision.v1", "decision": "approve" | "deny", "requestId": "..." } 를 제출할 수도 있습니다. 이 예약 메시지들은 일반 접근 평가보다 먼저 가로채이며 agent에게 절대 전달되지 않습니다. 명령 자체는 아무 권한도 주지 않습니다. 발신자는 해당 provider와 채널, tenant에 설정된 관리자 목록과 대조됩니다. 형식이 잘못된 명령이나 권한 없는 결정은 최종 거부입니다.

approval 모드를 벗어나면 그 채널의 기존 승인 권한이 한 번에 모두 취소됩니다. 이 버전에는 approval 모드를 유지한 채 개별 principal만 취소하는 기능이 없습니다.

메시지가 갈 곳 정하기

각 서술자는 받아들여진 인바운드 메시지의 정본 Virgo 목적지인 targetVsp와 기본 아웃바운드 대화를 지정합니다. 또한 어떤 대화가 범위 안인지도 한정합니다. Discord는 허용 guild와 채널 ID, Teams는 정확한 테넌트와 대화, Telegram은 허용 chat ID입니다.

회신 주소는 메시지마다 불변으로 기록되므로, agent의 답은 질문이 온 대화·thread·메시지로 돌아갑니다.

provider별로 할 수 있는 일

DiscordMicrosoft TeamsTelegram
전송 방식Gateway v10과 Bot API v10여러분의 HTTPS 엔드포인트 위 Bot Connector RESTBot API getUpdates long polling
기본 접근approval인증된 binding 안에서 openapproval
텍스트 한도provider 한도32,000 UTF-8 바이트4,096 유니코드 코드포인트
리치 카드쓰지 않음Adaptive 1.4, Hero, Thumbnail미지원
반응자기 것 추가·제거정확한 ID의 고정 카탈로그와 문서화된 별칭이모지 반응
인바운드 파일설정된 상한 안에서 첨부개인 채팅 한정, 관리형 파일 port 필요artifact port가 있으면 문서와 사진
아웃바운드 파일설정된 상한 안에서 첨부개인 채팅 한정, Teams 파일 동의 사용artifact port가 있으면 문서 전송
재전송 안전성—effect-key 멱등성 없음. 모호한 결과는 unknown으로 남음effect-key 멱등성 없음. 모호한 결과는 unknown으로 남음
배타성——봇 토큰마다 활성 poll 소유자 하나

Teams의 파일은 양방향 모두 개인 채팅 전용입니다. 보내는 쪽은 Teams 파일 동의를 사용합니다. 받는 쪽도 같은 개인 채팅 첨부를 대상으로 하며, supportsFiles가 켜져 있고 storeInbound를 제공하는 관리형 파일 port가 있으면 Teams가 보내는 인증된 첨부를 내려받아 저장하고, 그 port가 없으면 파일이 조용히 사라지는 대신 activity를 거부합니다. 그룹·채널 파일 전송은 Microsoft Graph와 사용자 인가가 필요하며, 어느 방향으로도 여기에 구현되어 있지 않습니다.

공용 대화 명령은 아직 동작하지 않습니다

/setseat, /listseat, 명시적인 ~seat 수신자는 설계되어 있고 소스도 있으며, 의도된 대화 모델의 일부이므로 provider 가이드에서도 설명합니다. 다만 오늘 설치된 채팅에서 기대할 동작은 아닙니다. 공용 Hub 대화가 설치된 채팅 ingress에 아직 구성되지 않았다고 소스 원장이 기록하고 있습니다. 동작이 아니라 설계로 받아들이세요.

다음

세 가이드는 모두 같은 모양입니다. provider에 무엇이 필요한지, 최소 권한은 무엇인지, 자격 증명은 어디에 두는지, 어떤 서술자가 필요한지, 접근을 어떻게 결정하는지, 이미 있는 설치본에 어떻게 등록하는지, 그리고 그 뒤에 무엇을 검증하는지입니다.

등록 자체는 Discord에 대해 정규 경로에서 수행되었습니다. 이미 존재하던 설치본에 adapter가 적재되었고 Host는 Gateway READY까지 도달했습니다. 검증은 거기서 멈춥니다. agent가 채팅 adapter를 통해 자신의 Seat을 claim하는 것, 사람의 메시지가 인바운드로 도착하는 것, 그에 상응하는 회신이 돌아 나가는 것은 어느 provider에서도 아직 검증되지 않았습니다.