@vibexnpm/talkx 8.2.0 → 8.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -78,6 +78,7 @@ await client.connect(jwtToken, { enablePush: true });
78
78
  | [push.md](docs/push.md) | **웹 푸시 알림.** 권한 lifecycle, 활성화 패턴 (자동 vs 사용자 액션), 디바이스 토글, 알림 클릭 라우팅 |
79
79
  | [webrtc.md](docs/webrtc.md) | 1:1 / 그룹 통화, 미디어 제어, 디바이스 관리, TURN 서버 |
80
80
  | [vote.md](docs/vote.md) | **투표.** 생성(멱등키 필수) · 투표/재투표 · 결과 마스킹 · 이미지 선택지 · 채팅 카드 렌더링 |
81
+ | [video-analysis.md](docs/video-analysis.md) | **영상 분석.** 사용 가능 여부·한도 · 업로드 · 접수(멱등키 필수) · 방 게시 · 상태 조회 · 취소 · 에러 코드 |
81
82
  | [events.md](docs/events.md) | 모든 이벤트 레퍼런스. 채팅 이벤트 처리 패턴 (`eventType` 분기 vs 상태 필드 렌더) |
82
83
  | [errors.md](docs/errors.md) | 에러 분류 (`PushErrorReason`, `ErrorTypes`), HTTP 상태 코드, 입력 제약 |
83
84
 
@@ -209,6 +210,8 @@ renderTranslatedText(translated.translatedText); // 요청자 전용 응답, 방
209
210
 
210
211
  요약/번역은 동기 호출이라 LLM 처리(수 초) 후 반환됩니다. 요약은 생성된 어시스턴트 메시지가 일반 `chatMessage` 이벤트로도 도착하고, 번역은 요청자 전용 응답으로만 반환됩니다.
211
212
 
213
+ 영상 분석(`analyzeVideoWithAssistant` · `analyzeVideo`)은 비동기 작업입니다 — 접수하면 `jobId` 가 돌아오고 결과는 조회하거나 방 메시지로 받습니다. [docs/video-analysis.md](docs/video-analysis.md) 를 따릅니다.
214
+
212
215
  ---
213
216
 
214
217
  ## CDN 사용
package/dist/index.d.ts CHANGED
@@ -501,6 +501,12 @@ export interface PmPromptPreviewResponse {
501
501
  composedPrompt: string;
502
502
  }
503
503
 
504
+ /** {@code leaveRoom} 옵션 — 방장의 «위임 후 나가기». */
505
+ export interface LeaveRoomOptions {
506
+ /** 방장을 넘겨받을 사람 userId. 방의 활성 사람 참가자이면서 활성 계정이어야 한다. 일반 참가자는 생략. */
507
+ newOwnerId?: string;
508
+ }
509
+
504
510
  /**
505
511
  * {@link ChatClient.inviteToGroupRoom} 의 신규 형식 입력. 회원 / 어시스턴트 동시 초대 지원.
506
512
  * 둘 중 하나 이상 필수.
@@ -522,6 +528,8 @@ export const RoomListEventType: {
522
528
  readonly ROOM_UPDATED: 'ROOM_UPDATED';
523
529
  readonly ROOM_KICKED: 'ROOM_KICKED';
524
530
  readonly ROOM_BANNED: 'ROOM_BANNED';
531
+ readonly ROOM_OWNER_CHANGED: 'ROOM_OWNER_CHANGED';
532
+ readonly ROOM_DELETED: 'ROOM_DELETED';
525
533
  readonly MESSAGE_RETENTION_CLEANUP: 'MESSAGE_RETENTION_CLEANUP';
526
534
  readonly ROOM_UNREAD_UPDATED: 'ROOM_UNREAD_UPDATED';
527
535
  };
@@ -1266,10 +1274,24 @@ export interface RoomMeta {
1266
1274
  }
1267
1275
 
1268
1276
  /** 채팅방 리스트 실시간 업데이트 이벤트. */
1277
+ /** 방 목록 이벤트의 사용자 정보 — 서버 {@code RoomListEvent.MemberInfo}. */
1278
+ export interface RoomListMemberInfo {
1279
+ userId: string;
1280
+ nickname?: string | null;
1281
+ profileUrl?: string | null;
1282
+ }
1283
+
1269
1284
  export interface RoomListUpdateEvent {
1270
1285
  eventType: RoomListEventTypeValue;
1271
1286
  roomId: string;
1272
1287
  actorId?: string;
1288
+ /**
1289
+ * 입장·퇴장·추방·차단한 사용자, 또는 {@code ROOM_OWNER_CHANGED} 의 새 방장(1명). 서버 {@code RoomListEvent.MemberInfo}.
1290
+ * {@code ROOM_JOINED}·{@code ROOM_LEFT}·{@code ROOM_KICKED}·{@code ROOM_BANNED}·{@code ROOM_OWNER_CHANGED} 에서만 채워진다.
1291
+ */
1292
+ members?: RoomListMemberInfo[];
1293
+ /** 이벤트 직후 활성 참가자 수 — 입장·퇴장·추방·차단·위임 이벤트에서 채워지고, {@code ROOM_DELETED} 는 0. */
1294
+ activeParticipantCount?: number;
1273
1295
  /** {@code MESSAGE_*} 이벤트의 방 마지막 메시지 시각(epoch millis). 그 외 이벤트에서는 undefined. */
1274
1296
  lastMessageAt?: number | null;
1275
1297
  /** 이벤트 발행 시각(epoch millis). */
@@ -1373,6 +1395,8 @@ export interface DocumentAnalysisProgress {
1373
1395
  * 렌더가 그대로 동작한다.
1374
1396
  *
1375
1397
  * 현재는 PM_BACKSTAGE(방당 단일 PM) 만 phase 를 발행 — 멘션/버튼/14인 경로는 본 이벤트 없이 typing 만.
1398
+ * 예외는 영상 분석 버튼({@code analyzeVideoWithAssistant})으로, 어시스턴트가 붙어 있는 방이면 방 종류와
1399
+ * 무관하게 `VIDEO_ANALYSIS` 를 발행한다(docs/video-analysis.md).
1376
1400
  */
1377
1401
 
1378
1402
  export interface AssistantProgressEvent {
@@ -1388,7 +1412,7 @@ export interface AssistantProgressEvent {
1388
1412
  /** 진행 주체 페르소나 ID. */
1389
1413
  personaId: string | null;
1390
1414
  /** 진행 단계 — `active:true` 일 때. 종료 시 null. */
1391
- phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'WRITING' | null;
1415
+ phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'VIDEO_ANALYSIS' | 'WRITING' | null;
1392
1416
  /** DOCUMENT_ANALYSIS의 실측 진행률. 같은 phase heartbeat 사이와 재입장 후에도 보존된다. */
1393
1417
  progress?: DocumentAnalysisProgress | null;
1394
1418
  /** phase 의 기본 표시 라벨(예: "생각 중…"). SDK 매핑 — 커스텀하려면 `phase` 사용. 종료 시 null. */
@@ -1416,7 +1440,10 @@ export interface AssistantProgressEvent {
1416
1440
  textAvailable?: boolean;
1417
1441
  /** 종료(DONE) 결과 — DONE 수신 시만. */
1418
1442
  status?: 'SUCCEEDED' | 'FAILED' | 'CANCELLED' | 'TIMEOUT' | null;
1419
- /** 종료(DONE, SUCCEEDED) 시 영속된 최종 메시지 ID. */
1443
+ /**
1444
+ * 종료(DONE) 시 방에 올라간 메시지 ID. 보통 `SUCCEEDED` 에만 있다.
1445
+ * 영상 분석은 실패 안내 메시지의 ID 가 `FAILED`·`TIMEOUT` 에도 실린다 — 성공 여부는 `status` 로 판정한다.
1446
+ */
1420
1447
  messageId?: string | null;
1421
1448
  /**
1422
1449
  * 종료 사유 — 'timeout'(TTL 만료). DONE 수신 해제엔 없음.
@@ -1456,7 +1483,7 @@ export interface AssistantRoomProgressEvent {
1456
1483
  /** 표시 기준이 된 stream (가장 최근 갱신). 없으면 null. */
1457
1484
  streamId: string | null;
1458
1485
  personaId: string | null;
1459
- phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'WRITING' | null;
1486
+ phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'VIDEO_ANALYSIS' | 'WRITING' | null;
1460
1487
  progress?: DocumentAnalysisProgress | null;
1461
1488
  label: string | null;
1462
1489
  /** 표시 기준 stream 의 누적 본문. `textAvailable:false` 거나 진행 중이 아니면 null. */
@@ -1469,7 +1496,7 @@ export interface AssistantRoomProgressEvent {
1469
1496
  export interface AssistantProgressStreamSnapshot {
1470
1497
  streamId: string;
1471
1498
  personaId: string | null;
1472
- phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'WRITING' | null;
1499
+ phase: 'THINKING' | 'SEARCHING' | 'PLANNING' | 'DOCUMENT_ANALYSIS' | 'VIDEO_ANALYSIS' | 'WRITING' | null;
1473
1500
  progress?: DocumentAnalysisProgress | null;
1474
1501
  label: string | null;
1475
1502
  text: string | null;
@@ -1946,6 +1973,10 @@ export interface TalkFlowClientEvents {
1946
1973
  roomListBanned: RoomListUpdateEvent;
1947
1974
  /** 본인이 영구 차단당함. */
1948
1975
  roomListSelfBanned: RoomListUpdateEvent;
1976
+ /** 방장 위임 (ROOM_OWNER_CHANGED) — actorId 는 이전 방장, members[0] 이 새 방장. */
1977
+ roomListOwnerChanged: RoomListUpdateEvent;
1978
+ /** 방장이 방을 삭제 (ROOM_DELETED) — 리스트에서 제거 + 열린 방 화면 닫기. actorId 는 삭제한 방장. */
1979
+ roomListDeleted: RoomListUpdateEvent;
1949
1980
  roomListRoomUpdated: RoomListUpdateEvent;
1950
1981
  /** 내가 어느 기기에서 읽든 방별 미독 절대값(+version)을 통지 — 크로스-디바이스 badge 동기화. */
1951
1982
  roomListUnreadUpdated: RoomUnreadUpdatedEvent;
@@ -2049,6 +2080,10 @@ export interface ChatClientEvents {
2049
2080
  roomListBanned: RoomListUpdateEvent;
2050
2081
  /** 본인이 영구 차단당함. */
2051
2082
  roomListSelfBanned: RoomListUpdateEvent;
2083
+ /** 방장 위임 (ROOM_OWNER_CHANGED) — actorId 는 이전 방장, members[0] 이 새 방장. */
2084
+ roomListOwnerChanged: RoomListUpdateEvent;
2085
+ /** 방장이 방을 삭제 (ROOM_DELETED) — 리스트에서 제거 + 열린 방 화면 닫기. actorId 는 삭제한 방장. */
2086
+ roomListDeleted: RoomListUpdateEvent;
2052
2087
  roomListRoomUpdated: RoomListUpdateEvent;
2053
2088
  /** 내가 어느 기기에서 읽든 방별 미독 절대값(+version)을 통지 — 크로스-디바이스 badge 동기화. */
2054
2089
  roomListUnreadUpdated: RoomUnreadUpdatedEvent;
@@ -2124,6 +2159,12 @@ export class ChatClient implements SdkEventEmitter<ChatClientEvents> {
2124
2159
  summarizeWithAssistant(roomId: string, options: SummarizeToolRequest): Promise<AssistantToolResult>;
2125
2160
  /** 특정 메시지 온디맨드 번역 (버튼 진입점, 동기, 요청자 전용 응답). */
2126
2161
  translateWithAssistant(roomId: string, options: TranslateToolRequest): Promise<OnDemandTranslationResponse>;
2162
+ uploadVideoAsset(file: File, options?: FileUploadOptions): Promise<VideoAsset>;
2163
+ analyzeVideo(analysis: VideoAnalysisRequest, options: VideoAnalysisOptions): Promise<VideoAnalysisJob>;
2164
+ analyzeVideoWithAssistant(roomId: string, request: RoomVideoAnalysisRequest, options: VideoAnalysisOptions): Promise<VideoAnalysisJob>;
2165
+ getVideoAnalysis(jobId: string): Promise<VideoAnalysisJob>;
2166
+ cancelVideoAnalysis(jobId: string): Promise<VideoAnalysisCancellation>;
2167
+ getVideoAnalysisCapabilities(): Promise<VideoAnalysisCapabilities>;
2127
2168
  /** Rolling 누적 요약 갱신 트리거 (비동기). 완료는 {@code summaryUpdate} 이벤트 + {@link getSummary} 로 확인. */
2128
2169
  refreshSummary(roomId: string, options?: RefreshSummaryOptions): Promise<RefreshSummaryResult>;
2129
2170
  /** Rolling 누적 요약 조회 — rollup + segment 페이지. 저장된 요약의 단일 진실 소스. */
@@ -2161,7 +2202,15 @@ export class ChatClient implements SdkEventEmitter<ChatClientEvents> {
2161
2202
  /** PM 프롬프트 합성 미리보기 (전역+회사+방) — 참여자 전체. */
2162
2203
  previewRoomPmPrompt(roomId: string): Promise<PmPromptPreviewResponse>;
2163
2204
  joinGroupRoom(roomId: string, password?: string): Promise<ChatRoomResponse>;
2164
- leaveRoom(roomId: string): Promise<void>;
2205
+ /**
2206
+ * 방 나가기. 방장은 {@code options.newOwnerId} 로 «위임 후 나가기» — 없으면 409 {@code ROOM_OWNER_CANNOT_LEAVE}.
2207
+ * 방을 없애고 나가려면 {@link deleteRoom}.
2208
+ */
2209
+ leaveRoom(roomId: string, options?: LeaveRoomOptions): Promise<void>;
2210
+ /** 방장 위임 — 방장은 방에 남고 MEMBER 가 된다. 방장(OWNER) 전용. 갱신된 방 상세(역할 반영)를 돌려준다. */
2211
+ transferOwnership(roomId: string, newOwnerId: string): Promise<ChatRoomResponse>;
2212
+ /** 방 삭제(소프트) — 방장(OWNER) 전용. 참가자 전원 퇴장, 이후 enterRoom·getRoomInfo 403·joinGroupRoom 404. 본인 구독 자동 해제. */
2213
+ deleteRoom(roomId: string): Promise<void>;
2165
2214
  updateGroupRoom(roomId: string, data: UpdateGroupRoomData): Promise<ChatRoomResponse>;
2166
2215
  inviteToGroupRoom(roomId: string, userIds: string[]): Promise<ChatRoomResponse>;
2167
2216
  inviteToGroupRoom(roomId: string, data: InviteToRoomData): Promise<ChatRoomResponse>;
@@ -2567,6 +2616,12 @@ export default class TalkFlowClient implements SdkEventEmitter<TalkFlowClientEve
2567
2616
  summarizeWithAssistant(roomId: string, options: SummarizeToolRequest): Promise<AssistantToolResult>;
2568
2617
  /** 특정 메시지 온디맨드 번역 (버튼 진입점, 동기, 요청자 전용 응답). */
2569
2618
  translateWithAssistant(roomId: string, options: TranslateToolRequest): Promise<OnDemandTranslationResponse>;
2619
+ uploadVideoAsset(file: File, options?: FileUploadOptions): Promise<VideoAsset>;
2620
+ analyzeVideo(analysis: VideoAnalysisRequest, options: VideoAnalysisOptions): Promise<VideoAnalysisJob>;
2621
+ analyzeVideoWithAssistant(roomId: string, request: RoomVideoAnalysisRequest, options: VideoAnalysisOptions): Promise<VideoAnalysisJob>;
2622
+ getVideoAnalysis(jobId: string): Promise<VideoAnalysisJob>;
2623
+ cancelVideoAnalysis(jobId: string): Promise<VideoAnalysisCancellation>;
2624
+ getVideoAnalysisCapabilities(): Promise<VideoAnalysisCapabilities>;
2570
2625
  /** Rolling 누적 요약 갱신 트리거 (비동기). 완료는 {@code summaryUpdate} 이벤트 + {@link getSummary} 로 확인. */
2571
2626
  refreshSummary(roomId: string, options?: RefreshSummaryOptions): Promise<RefreshSummaryResult>;
2572
2627
  /** Rolling 누적 요약 조회 — rollup + segment 페이지. 저장된 요약의 단일 진실 소스. */
@@ -2604,7 +2659,15 @@ export default class TalkFlowClient implements SdkEventEmitter<TalkFlowClientEve
2604
2659
  /** PM 프롬프트 합성 미리보기 (전역+회사+방) — 참여자 전체. */
2605
2660
  previewRoomPmPrompt(roomId: string): Promise<PmPromptPreviewResponse>;
2606
2661
  joinGroupRoom(roomId: string, password?: string): Promise<ChatRoomResponse>;
2607
- leaveRoom(roomId: string): Promise<void>;
2662
+ /**
2663
+ * 방 나가기. 방장은 {@code options.newOwnerId} 로 «위임 후 나가기» — 없으면 409 {@code ROOM_OWNER_CANNOT_LEAVE}.
2664
+ * 방을 없애고 나가려면 {@link deleteRoom}.
2665
+ */
2666
+ leaveRoom(roomId: string, options?: LeaveRoomOptions): Promise<void>;
2667
+ /** 방장 위임 — 방장은 방에 남고 MEMBER 가 된다. 방장(OWNER) 전용. 갱신된 방 상세(역할 반영)를 돌려준다. */
2668
+ transferOwnership(roomId: string, newOwnerId: string): Promise<ChatRoomResponse>;
2669
+ /** 방 삭제(소프트) — 방장(OWNER) 전용. 참가자 전원 퇴장, 이후 enterRoom·getRoomInfo 403·joinGroupRoom 404. 본인 구독 자동 해제. */
2670
+ deleteRoom(roomId: string): Promise<void>;
2608
2671
  updateGroupRoom(roomId: string, data: UpdateGroupRoomData): Promise<ChatRoomResponse>;
2609
2672
  inviteToGroupRoom(roomId: string, userIds: string[]): Promise<ChatRoomResponse>;
2610
2673
  inviteToGroupRoom(roomId: string, data: InviteToRoomData): Promise<ChatRoomResponse>;
@@ -2815,3 +2878,35 @@ export class RoomUnreadReconciler {
2815
2878
  /** 전체 초기화. */
2816
2879
  clear(): void;
2817
2880
  }
2881
+
2882
+
2883
+ /** Caller retains this key and reuses it after a lost response. */
2884
+ export interface VideoAnalysisOptions { idempotencyKey: string; }
2885
+ export type VideoAnalysisSource =
2886
+ | { type: 'UPLOADED_ASSET'; assetId: string; startMs?: number; endMs?: number }
2887
+ | { type: 'CHAT_ATTACHMENT'; roomId: string; messageId: string; attachmentId: string; startMs?: number; endMs?: number };
2888
+ export interface VideoAnalysisRequest { instruction: string; locale?: string; sources: VideoAnalysisSource[]; }
2889
+ export interface RoomVideoAnalysisRequest { personaId: string; triggerMessageId: string; analysis: VideoAnalysisRequest; }
2890
+ export interface VideoAsset { assetId: string; fileName: string; mimeType: string; sizeBytes: number; durationMs: number; expiresAt: string; }
2891
+ export interface VideoAnalysisResult {
2892
+ answerMarkdown: string;
2893
+ evidence: { sourceId: string; startMs: number | null; endMs: number | null; modality: 'VISUAL' | 'AUDIO' | 'BOTH'; observation: string }[];
2894
+ limitations: string[];
2895
+ /** Requested temporal coverage and sampling; not a guarantee every frame was inspected. */
2896
+ coverage: { sourceId: string; startMs: number; endMs: number; framesPerSecond: number }[];
2897
+ model: string; promptVersion: string;
2898
+ usage: { uncachedInputTokens: number; cachedInputTokens: number; outputTokens: number; thinkingTokens: number };
2899
+ }
2900
+ export interface VideoAnalysisJob {
2901
+ jobId: string; status: 'QUEUED' | 'RUNNING' | 'SUCCEEDED' | 'FAILED' | 'CANCELLED'; phase: string;
2902
+ errorCode: string | null; detail: string | null;
2903
+ sources: { sourceId: string; assetId: string | null; roomId: string | null; messageId: string | null; attachmentId: string | null; startMs: number | null; endMs: number | null }[];
2904
+ result: VideoAnalysisResult | null; createdAt: string; deadlineAt: string;
2905
+ roomId: string | null; streamId: string | null; resultMessageId: string | null; deliveryPending: boolean;
2906
+ }
2907
+ export interface VideoAnalysisCapabilities {
2908
+ available: boolean; model: string; standaloneUploadConfigured: boolean; maxSources: number;
2909
+ maxBytesPerSource: number; maxTotalDurationMs: number; framesPerSecond: number; mimeTypes: string[];
2910
+ }
2911
+
2912
+ export interface VideoAnalysisCancellation { jobId: string; status: VideoAnalysisJob['status']; deliveryPending: boolean; }