connectbase-client 4.4.0 → 5.0.0

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/CHANGELOG.md CHANGED
@@ -3,6 +3,77 @@
3
3
  본 SDK 의 모든 주요 변경사항을 [Keep a Changelog](https://keepachangelog.com/ko/1.1.0/) 형식으로 기록합니다.
4
4
  버전은 [Semantic Versioning](https://semver.org/lang/ko/) 을 따릅니다.
5
5
 
6
+ ## [5.0.0] - 2026-07-27
7
+
8
+ ### BREAKING — AI 스트리밍 `onError` 가 문자열이 아닌 `AIError` 객체를 전달
9
+
10
+ `cb.ai.chatStream` 의 `onError` 시그니처가 `(error: string) => void` 에서
11
+ `(error: AIError) => void` 로 바뀌었다. 문자열이 필요하면 `error.message` 를 쓴다.
12
+ `cb.realtime.stream` 의 `onError` 는 이전에도 `Error` 였고 `AIError` 가 그 하위 타입이라
13
+ 타입상 호환된다.
14
+
15
+ ```diff
16
+ - onError: (err) => showError(err)
17
+ + onError: (err) => {
18
+ + if (err.code === 'rate_limit_exceeded') backOff(err.retryAfter ?? 30)
19
+ + else if (err.retryable) scheduleRetry()
20
+ + else showError(err.message)
21
+ + }
22
+ ```
23
+
24
+ ### Fixed — AI 실패 시 `onError` 페이로드가 비어 있던 문제 (platform-issue 019fa21c)
25
+
26
+ 자체 호스팅 모델이 내려간 동안 AI 호출이 실패하면 `onError` 로 온 값을 `JSON.stringify`
27
+ 했을 때 **빈 객체 `{}`** 였다. 문서에 있는 에러 코드(`provider_timeout`,
28
+ `rate_limit_exceeded`, `service_unavailable` …)가 하나도 오지 않아, 대응이 정반대인
29
+ 실패들(호출을 줄여야 함 / 기다렸다 재시도 / 재시도 금지)을 구분할 수 없었다.
30
+
31
+ 원인이 세 겹이었고 모두 고쳤다.
32
+
33
+ 1. **서버가 코드를 안 보냈다.** socket-server 는 모든 스트리밍 실패를 단일
34
+ `STREAM_ERROR` + 고정 문구로 뭉갰다. 이제 `provider_timeout` / `service_unavailable` /
35
+ `rate_limit_exceeded` / `quota_exceeded` / `provider_error` / `invalid_request` /
36
+ `config_error` / `unauthorized` / `stream_failed` 로 분류해 보낸다.
37
+ 2. **SDK 가 코드를 버렸다.** 서버가 보낸 `code` 를 무시하고 `new Error(message)` 로
38
+ 감쌌다. 이제 `AIError` 로 정규화해 `code` · `retryable` · `status` · `provider` ·
39
+ `model` · `retryAfter` · `detailCode` 를 모두 보존한다.
40
+ 3. **`Error` 는 `{}` 로 직렬화된다.** `message`/`stack` 이 non-enumerable 이기 때문.
41
+ `AIError` · `ApiError` · `GameError` 에 `toJSON()` 을 추가해 `JSON.stringify(err)` 가
42
+ 구조를 그대로 출력한다.
43
+
44
+ ### Fixed — `cb.ai.chat` 이 거절 사유를 전달하지 못하던 문제
45
+
46
+ AI 에러 응답 `{"error":"provider_timeout","message":"..."}` 에서 HTTP 클라이언트가
47
+ `error`(머신용 코드)를 사람이 읽을 메시지로 오인해, `ApiError.code` 는 `undefined` 가 되고
48
+ 진짜 `message` 는 버려졌다. 이제 코드와 메시지를 모두 보존하며, `provider`/`model` 은
49
+ `details` 에 실린다. `{ error: "사람이 읽는 문장" }` 형태의 레거시 응답은 그대로 동작한다.
50
+
51
+ ### Added
52
+
53
+ - `AIError` 클래스와 `AIErrorCode` 타입, `toAIError()` 헬퍼를 export.
54
+ - 실시간 연결 종료/유실로 중단된 AI 스트림도 `service_unavailable`(retryable) 로 분류해 전달.
55
+
56
+ ## [4.4.1] - 2026-07-26
57
+
58
+ ### Fixed — 로그인·가입 응답의 refresh 쿠키가 저장되지 않아 세션 복구가 항상 실패하던 문제
59
+
60
+ `persistence: 'none'`(권장·기본값) + `autoRestoreSession: true` 조합에서 **새로고침하면 항상
61
+ 로그아웃**되던 버그를 고쳤다 (platform-issue 019f9e23).
62
+
63
+ `fetchCredentialsForPath` 가 `/v1/public/` prefix 전체를 `credentials: 'omit'` 으로 보내고 있었는데,
64
+ 로그인·가입 엔드포인트(`/v1/public/app-members/signin` · `signup`)가 바로 그 아래였다. `omit` 으로
65
+ 보낸 요청은 브라우저가 응답의 `Set-Cookie` 를 **폐기**하므로 멤버 refresh 쿠키가 아예 저장되지
66
+ 않았고, 이후 `/v1/auth/re-issue` 는 쿠키가 없어 401 이 됐다. 즉 "안전한 기본값" 과 "동작하는
67
+ 세션" 중 하나를 포기해야 하는 상태였다.
68
+
69
+ - 쿠키를 주고받는 공개 인증 경로(`signin` / `signup` / `signout`)만 화이트리스트로 `'include'`.
70
+ - 그 밖의 `/v1/public/*` 는 그대로 `'omit'` — `*.web.connectbase.world` 배포 시 부모 도메인
71
+ 콘솔 쿠키가 딸려오는 회귀(019ea60d)는 계속 차단된다.
72
+
73
+ > 서버 측에도 짝이 되는 수정이 함께 배포됐다. `/v1/auth/re-issue` 의 인증 미들웨어가 앱별
74
+ > 쿠키 이름(`cb_member_refresh_token_<appID>`) 대신 legacy 단일 이름만 찾고 있어서, 쿠키가
75
+ > 저장된 뒤에도 401 이 났다. SDK 만 올리면 동작하지 않으므로 두 수정이 모두 필요하다.
76
+
6
77
  ## [4.4.0] - 2026-07-25
7
78
 
8
79
  ### Changed — `cb.publicKey.*` 를 service_role 함수에서 호출 가능 (`publickey:read` / `publickey:manage`)