connectbase-client 3.18.0 → 3.20.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/dist/index.d.mts CHANGED
@@ -6952,24 +6952,33 @@ interface CreateDocumentRequest {
6952
6952
  * 비어있으면 서버가 매직 바이트로 자동 추정 — 정확도를 위해 명시 권장.
6953
6953
  */
6954
6954
  mime_type?: string;
6955
+ /**
6956
+ * 클라이언트가 지정하는 멱등(upsert) 키. 같은 지식 베이스 안에서 유일하다.
6957
+ * 같은 `external_id` 로 다시 `addDocument` 하면 새 문서를 만들지 않고 기존 문서를
6958
+ * 교체(update)한다 — `listDocuments` 로 기존 문서를 찾아 지울 필요 없이
6959
+ * idempotent 한 동기화가 가능하다. 문서 id 도 그대로 유지된다.
6960
+ */
6961
+ external_id?: string;
6955
6962
  metadata?: Record<string, unknown>;
6956
6963
  }
6957
6964
  /**
6958
- * 문서 수정 요청.
6965
+ * 문서 update/upsert 요청. 보낸 필드만 교체된다 (생략한 필드는 변경 없음).
6959
6966
  *
6960
6967
  * `content` / `file_content` / `metadata` 중 하나라도 보내면 서버가 전체 재색인을 수행한다
6961
6968
  * (기존 청크 삭제 → 재청킹 → 재색인). RAG 특성상 콘텐츠가 바뀌면 청크 경계가 바뀌어
6962
6969
  * 부분 수정이 불가능하며, 재색인 시 색인 토큰이 다시 과금된다.
6963
- * `name` 만 보내면 재색인 없이 라벨만 변경된다. 모든 필드는 옵셔널.
6970
+ * `name` / `external_id` 만 보내면 재색인 없이 라벨·멱등 키만 변경된다.
6971
+ * 문서 id 는 항상 유지되므로 검색 결과의 `document_id` 참조가 깨지지 않는다.
6964
6972
  */
6965
6973
  interface UpdateDocumentRequest {
6966
6974
  name?: string;
6967
6975
  content?: string;
6968
- /** base64 인코딩 바이너리 파일 재업로드 (PDF/DOCX/text). source_type 무관하게 추출. */
6976
+ /** base64 인코딩 파일 (파일 재업로드, PDF/DOCX/text). content 보다 우선하며 source_type 무관하게 추출. */
6969
6977
  file_content?: string;
6970
6978
  /** file_content 의 MIME. 비어있으면 서버 자동 추정. */
6971
6979
  mime_type?: string;
6972
6980
  metadata?: Record<string, unknown>;
6981
+ external_id?: string;
6973
6982
  }
6974
6983
  interface DocumentResponse {
6975
6984
  id: string;
@@ -6977,6 +6986,7 @@ interface DocumentResponse {
6977
6986
  source_type: string;
6978
6987
  mime_type?: string;
6979
6988
  source_url?: string;
6989
+ external_id?: string;
6980
6990
  file_size: number;
6981
6991
  chunk_count: number;
6982
6992
  status: 'pending' | 'processing' | 'ready' | 'failed';
@@ -7035,6 +7045,14 @@ interface KnowledgeSearchResponse {
7035
7045
  query: string;
7036
7046
  results: KnowledgeSearchResult[];
7037
7047
  total: number;
7048
+ /**
7049
+ * 이 응답이 agentic 다중검색으로 생성됐는지 여부. `agentic: true` 를 보냈더라도
7050
+ * AI provider 미설정·LLM 오류로 단일 키워드 검색에 폴백되면 `false` — 옵션이
7051
+ * placebo 가 되지 않도록 실제 수행 여부를 신호한다.
7052
+ */
7053
+ agentic?: boolean;
7054
+ /** 수행된 agentic 검색 라운드 수 (1~2). 0 또는 미존재는 폴백을 의미. */
7055
+ agentic_rounds?: number;
7038
7056
  }
7039
7057
 
7040
7058
  /**
@@ -7113,9 +7131,60 @@ declare class KnowledgeAPI {
7113
7131
  * source_type: 'url',
7114
7132
  * source_url: 'https://example.com/help.html'
7115
7133
  * })
7134
+ *
7135
+ * // external_id 로 idempotent 동기화 (빌드 스크립트 등)
7136
+ * // 같은 external_id 로 다시 호출하면 기존 문서를 교체한다 (문서 id 유지).
7137
+ * await cb.knowledge.addDocument('kb-id', {
7138
+ * name: '블로그: 제목',
7139
+ * source_type: 'text',
7140
+ * content: '...',
7141
+ * external_id: 'blog/my-post-slug',
7142
+ * })
7116
7143
  * ```
7117
7144
  */
7118
7145
  addDocument(kbID: string, data: CreateDocumentRequest): Promise<DocumentResponse>;
7146
+ /**
7147
+ * 문서 수정 (update/upsert)
7148
+ *
7149
+ * 기존 문서의 내용·이름·메타데이터를 교체합니다. **문서 id 는 그대로 유지**되므로
7150
+ * 검색 결과의 `document_id` 를 외부에서 참조(인용·캐시)해도 편집 후 깨지지 않습니다.
7151
+ * 보낸 필드만 교체되며, 내용/이름/메타데이터가 실제로 바뀌면 자동으로 재청킹·재색인됩니다.
7152
+ *
7153
+ * @param kbID - 지식 베이스 ID
7154
+ * @param docID - 문서 ID
7155
+ * @param data - 변경할 필드 (생략한 필드는 변경 없음)
7156
+ * @returns 수정된 문서 정보
7157
+ *
7158
+ * @example
7159
+ * ```typescript
7160
+ * // 내용만 교체 — document_id 는 그대로
7161
+ * const doc = await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7162
+ * content: '갱신된 환불 정책...',
7163
+ * })
7164
+ *
7165
+ * // 이름 + 메타데이터 교체
7166
+ * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7167
+ * name: 'FAQ (2026)',
7168
+ * metadata: { tag: 'faq', updated: '2026-05' },
7169
+ * })
7170
+ * ```
7171
+ */
7172
+ updateDocument(kbID: string, docID: string, data: UpdateDocumentRequest): Promise<DocumentResponse>;
7173
+ /**
7174
+ * 파일로 문서 수정 (PDF / DOCX / text 파일 재업로드).
7175
+ *
7176
+ * [`addDocumentFromFile`](#addDocumentFromFile) 의 update 버전. 문서 id 는 유지됩니다.
7177
+ *
7178
+ * @param kbID - Knowledge Base ID
7179
+ * @param docID - 문서 ID
7180
+ * @param file - 새 파일. `File` (DOM) / `Blob` / `{ data, mimeType, name }` (Node) 모두 가능
7181
+ * @param options - name / metadata 오버라이드
7182
+ * @returns 수정된 문서 정보
7183
+ */
7184
+ updateDocumentFromFile(kbID: string, docID: string, file: KnowledgeFileInput, options?: {
7185
+ name?: string;
7186
+ metadata?: Record<string, unknown>;
7187
+ }): Promise<DocumentResponse>;
7119
7188
  /**
7120
7189
  * 파일을 KB 에 추가 (PDF / DOCX / text 파일).
7121
7190
  *
@@ -7160,31 +7229,6 @@ declare class KnowledgeAPI {
7160
7229
  name?: string;
7161
7230
  metadata?: Record<string, unknown>;
7162
7231
  }): Promise<DocumentResponse>;
7163
- /**
7164
- * 문서 수정 (재색인)
7165
- *
7166
- * `content` / `file_content` / `metadata` 중 하나라도 포함하면 전체 재색인이 일어나며
7167
- * 색인 토큰이 다시 과금됩니다. `name` 만 보내면 재색인 없이 라벨만 변경됩니다.
7168
- * 재색인 시 서버는 status='pending' 으로 즉시 응답하고 색인은 백그라운드로 진행됩니다
7169
- * (addDocument 와 동일) — get/listDocuments 로 'ready' 전환을 확인하세요.
7170
- *
7171
- * @param kbID - 지식 베이스 ID
7172
- * @param docID - 문서 ID
7173
- * @param data - 수정 요청 (모든 필드 옵셔널)
7174
- * @returns 수정된 문서 정보
7175
- *
7176
- * @example
7177
- * ```typescript
7178
- * // 내용 갱신 (전체 재색인 발생)
7179
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7180
- * content: '환불은 구매 후 14일 이내에 가능합니다...'
7181
- * })
7182
- *
7183
- * // 이름만 변경 (재색인 없음)
7184
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', { name: '환불 정책 v2' })
7185
- * ```
7186
- */
7187
- updateDocument(kbID: string, docID: string, data: UpdateDocumentRequest): Promise<DocumentResponse>;
7188
7232
  /**
7189
7233
  * 문서 목록 조회
7190
7234
  *
@@ -7285,6 +7329,11 @@ interface AISource {
7285
7329
  }
7286
7330
  interface AIChatResponse {
7287
7331
  content: string;
7332
+ /**
7333
+ * 추론 모델(Qwen3 reasoning, OpenAI o-series, DeepSeek-R1 등)의 사고 과정.
7334
+ * 최종 답변(`content`)과 분리되어 제공됩니다. 추론 모델이 아니면 비어 있습니다.
7335
+ */
7336
+ reasoning?: string;
7288
7337
  finishReason?: string;
7289
7338
  usage?: {
7290
7339
  promptTokens: number;
@@ -7296,9 +7345,30 @@ interface AIChatResponse {
7296
7345
  toolCalls?: AIToolCall[];
7297
7346
  sources?: AISource[];
7298
7347
  }
7348
+ /**
7349
+ * Agentic 검색의 한 단계 진행 상황. `chatStream({ agentic: true })` 시
7350
+ * `onSearching` 콜백으로 실시간 전달되어 "검색 중…" 진행 UI 를 구성할 수 있다.
7351
+ */
7352
+ interface AgenticSearchProgress {
7353
+ /** 'query_generation' = 검색어 생성 중, 'searching' = 검색 실행 중, 'complete' = 검색 종료 */
7354
+ phase: 'query_generation' | 'searching' | 'complete';
7355
+ /** 검색 라운드 (1~2). agentic 은 결과가 부족하면 2라운드까지 수행. */
7356
+ round?: number;
7357
+ /** 이 라운드에서 생성된 검색 쿼리들 (phase='searching'). */
7358
+ queries?: string[];
7359
+ /** phase='complete': 누적 결과 청크 수. */
7360
+ results?: number;
7361
+ /** phase='complete': 총 검색 라운드 수. 0 은 폴백(단일 키워드 검색)을 의미. */
7362
+ rounds?: number;
7363
+ }
7299
7364
  interface AIStreamChunk {
7300
7365
  type?: 'sources' | 'token' | 'searching' | 'tool_start' | 'tool_end' | 'heartbeat';
7301
7366
  content: string;
7367
+ /**
7368
+ * 추론 모델의 사고 과정 델타. 추론 구간의 청크는 `content`가 비어 있고
7369
+ * `reasoning`만 채워져 전달됩니다.
7370
+ */
7371
+ reasoning?: string;
7302
7372
  finishReason?: string;
7303
7373
  done: boolean;
7304
7374
  toolCalls?: AIToolCall[];
@@ -7309,6 +7379,7 @@ interface AIStreamChunk {
7309
7379
  result?: string;
7310
7380
  success?: boolean;
7311
7381
  durationMs?: number;
7382
+ searching?: AgenticSearchProgress;
7312
7383
  }
7313
7384
 
7314
7385
  /**
@@ -7352,6 +7423,7 @@ declare class AIAPI {
7352
7423
  * knowledgeBaseId: 'kb-id',
7353
7424
  * }, {
7354
7425
  * onSources: (sources) => console.log('참조:', sources),
7426
+ * onReasoning: (reasoning) => process.stdout.write(reasoning),
7355
7427
  * onToken: (content) => process.stdout.write(content),
7356
7428
  * onDone: () => console.log('\\n완료'),
7357
7429
  * onError: (error) => console.error('에러:', error)
@@ -7360,8 +7432,19 @@ declare class AIAPI {
7360
7432
  */
7361
7433
  chatStream(request: AIChatRequest, callbacks: {
7362
7434
  onSources?: (sources: AISource[]) => void;
7435
+ /**
7436
+ * 추론 모델의 사고 과정 델타. 추론 모델(Qwen3 reasoning, o-series 등)을
7437
+ * 사용할 때만 호출되며, 최종 답변은 `onToken`으로 별도 전달됩니다.
7438
+ */
7439
+ onReasoning?: (reasoning: string) => void;
7363
7440
  onToken?: (content: string) => void;
7364
7441
  onToolEvent?: (event: AIToolEvent) => void;
7442
+ /**
7443
+ * Agentic 검색(`agentic: true`) 진행 상황. agentic 검색이 검색어를
7444
+ * 생성하고 다중 라운드로 검색하는 각 단계마다 호출되어, "검색 중…"
7445
+ * 진행 UI 를 구성할 수 있다. agentic 미사용 시 호출되지 않는다.
7446
+ */
7447
+ onSearching?: (progress: AgenticSearchProgress) => void;
7365
7448
  onDone?: () => void;
7366
7449
  onError?: (error: string) => void;
7367
7450
  }): Promise<void>;
package/dist/index.d.ts CHANGED
@@ -6952,24 +6952,33 @@ interface CreateDocumentRequest {
6952
6952
  * 비어있으면 서버가 매직 바이트로 자동 추정 — 정확도를 위해 명시 권장.
6953
6953
  */
6954
6954
  mime_type?: string;
6955
+ /**
6956
+ * 클라이언트가 지정하는 멱등(upsert) 키. 같은 지식 베이스 안에서 유일하다.
6957
+ * 같은 `external_id` 로 다시 `addDocument` 하면 새 문서를 만들지 않고 기존 문서를
6958
+ * 교체(update)한다 — `listDocuments` 로 기존 문서를 찾아 지울 필요 없이
6959
+ * idempotent 한 동기화가 가능하다. 문서 id 도 그대로 유지된다.
6960
+ */
6961
+ external_id?: string;
6955
6962
  metadata?: Record<string, unknown>;
6956
6963
  }
6957
6964
  /**
6958
- * 문서 수정 요청.
6965
+ * 문서 update/upsert 요청. 보낸 필드만 교체된다 (생략한 필드는 변경 없음).
6959
6966
  *
6960
6967
  * `content` / `file_content` / `metadata` 중 하나라도 보내면 서버가 전체 재색인을 수행한다
6961
6968
  * (기존 청크 삭제 → 재청킹 → 재색인). RAG 특성상 콘텐츠가 바뀌면 청크 경계가 바뀌어
6962
6969
  * 부분 수정이 불가능하며, 재색인 시 색인 토큰이 다시 과금된다.
6963
- * `name` 만 보내면 재색인 없이 라벨만 변경된다. 모든 필드는 옵셔널.
6970
+ * `name` / `external_id` 만 보내면 재색인 없이 라벨·멱등 키만 변경된다.
6971
+ * 문서 id 는 항상 유지되므로 검색 결과의 `document_id` 참조가 깨지지 않는다.
6964
6972
  */
6965
6973
  interface UpdateDocumentRequest {
6966
6974
  name?: string;
6967
6975
  content?: string;
6968
- /** base64 인코딩 바이너리 파일 재업로드 (PDF/DOCX/text). source_type 무관하게 추출. */
6976
+ /** base64 인코딩 파일 (파일 재업로드, PDF/DOCX/text). content 보다 우선하며 source_type 무관하게 추출. */
6969
6977
  file_content?: string;
6970
6978
  /** file_content 의 MIME. 비어있으면 서버 자동 추정. */
6971
6979
  mime_type?: string;
6972
6980
  metadata?: Record<string, unknown>;
6981
+ external_id?: string;
6973
6982
  }
6974
6983
  interface DocumentResponse {
6975
6984
  id: string;
@@ -6977,6 +6986,7 @@ interface DocumentResponse {
6977
6986
  source_type: string;
6978
6987
  mime_type?: string;
6979
6988
  source_url?: string;
6989
+ external_id?: string;
6980
6990
  file_size: number;
6981
6991
  chunk_count: number;
6982
6992
  status: 'pending' | 'processing' | 'ready' | 'failed';
@@ -7035,6 +7045,14 @@ interface KnowledgeSearchResponse {
7035
7045
  query: string;
7036
7046
  results: KnowledgeSearchResult[];
7037
7047
  total: number;
7048
+ /**
7049
+ * 이 응답이 agentic 다중검색으로 생성됐는지 여부. `agentic: true` 를 보냈더라도
7050
+ * AI provider 미설정·LLM 오류로 단일 키워드 검색에 폴백되면 `false` — 옵션이
7051
+ * placebo 가 되지 않도록 실제 수행 여부를 신호한다.
7052
+ */
7053
+ agentic?: boolean;
7054
+ /** 수행된 agentic 검색 라운드 수 (1~2). 0 또는 미존재는 폴백을 의미. */
7055
+ agentic_rounds?: number;
7038
7056
  }
7039
7057
 
7040
7058
  /**
@@ -7113,9 +7131,60 @@ declare class KnowledgeAPI {
7113
7131
  * source_type: 'url',
7114
7132
  * source_url: 'https://example.com/help.html'
7115
7133
  * })
7134
+ *
7135
+ * // external_id 로 idempotent 동기화 (빌드 스크립트 등)
7136
+ * // 같은 external_id 로 다시 호출하면 기존 문서를 교체한다 (문서 id 유지).
7137
+ * await cb.knowledge.addDocument('kb-id', {
7138
+ * name: '블로그: 제목',
7139
+ * source_type: 'text',
7140
+ * content: '...',
7141
+ * external_id: 'blog/my-post-slug',
7142
+ * })
7116
7143
  * ```
7117
7144
  */
7118
7145
  addDocument(kbID: string, data: CreateDocumentRequest): Promise<DocumentResponse>;
7146
+ /**
7147
+ * 문서 수정 (update/upsert)
7148
+ *
7149
+ * 기존 문서의 내용·이름·메타데이터를 교체합니다. **문서 id 는 그대로 유지**되므로
7150
+ * 검색 결과의 `document_id` 를 외부에서 참조(인용·캐시)해도 편집 후 깨지지 않습니다.
7151
+ * 보낸 필드만 교체되며, 내용/이름/메타데이터가 실제로 바뀌면 자동으로 재청킹·재색인됩니다.
7152
+ *
7153
+ * @param kbID - 지식 베이스 ID
7154
+ * @param docID - 문서 ID
7155
+ * @param data - 변경할 필드 (생략한 필드는 변경 없음)
7156
+ * @returns 수정된 문서 정보
7157
+ *
7158
+ * @example
7159
+ * ```typescript
7160
+ * // 내용만 교체 — document_id 는 그대로
7161
+ * const doc = await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7162
+ * content: '갱신된 환불 정책...',
7163
+ * })
7164
+ *
7165
+ * // 이름 + 메타데이터 교체
7166
+ * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7167
+ * name: 'FAQ (2026)',
7168
+ * metadata: { tag: 'faq', updated: '2026-05' },
7169
+ * })
7170
+ * ```
7171
+ */
7172
+ updateDocument(kbID: string, docID: string, data: UpdateDocumentRequest): Promise<DocumentResponse>;
7173
+ /**
7174
+ * 파일로 문서 수정 (PDF / DOCX / text 파일 재업로드).
7175
+ *
7176
+ * [`addDocumentFromFile`](#addDocumentFromFile) 의 update 버전. 문서 id 는 유지됩니다.
7177
+ *
7178
+ * @param kbID - Knowledge Base ID
7179
+ * @param docID - 문서 ID
7180
+ * @param file - 새 파일. `File` (DOM) / `Blob` / `{ data, mimeType, name }` (Node) 모두 가능
7181
+ * @param options - name / metadata 오버라이드
7182
+ * @returns 수정된 문서 정보
7183
+ */
7184
+ updateDocumentFromFile(kbID: string, docID: string, file: KnowledgeFileInput, options?: {
7185
+ name?: string;
7186
+ metadata?: Record<string, unknown>;
7187
+ }): Promise<DocumentResponse>;
7119
7188
  /**
7120
7189
  * 파일을 KB 에 추가 (PDF / DOCX / text 파일).
7121
7190
  *
@@ -7160,31 +7229,6 @@ declare class KnowledgeAPI {
7160
7229
  name?: string;
7161
7230
  metadata?: Record<string, unknown>;
7162
7231
  }): Promise<DocumentResponse>;
7163
- /**
7164
- * 문서 수정 (재색인)
7165
- *
7166
- * `content` / `file_content` / `metadata` 중 하나라도 포함하면 전체 재색인이 일어나며
7167
- * 색인 토큰이 다시 과금됩니다. `name` 만 보내면 재색인 없이 라벨만 변경됩니다.
7168
- * 재색인 시 서버는 status='pending' 으로 즉시 응답하고 색인은 백그라운드로 진행됩니다
7169
- * (addDocument 와 동일) — get/listDocuments 로 'ready' 전환을 확인하세요.
7170
- *
7171
- * @param kbID - 지식 베이스 ID
7172
- * @param docID - 문서 ID
7173
- * @param data - 수정 요청 (모든 필드 옵셔널)
7174
- * @returns 수정된 문서 정보
7175
- *
7176
- * @example
7177
- * ```typescript
7178
- * // 내용 갱신 (전체 재색인 발생)
7179
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
7180
- * content: '환불은 구매 후 14일 이내에 가능합니다...'
7181
- * })
7182
- *
7183
- * // 이름만 변경 (재색인 없음)
7184
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', { name: '환불 정책 v2' })
7185
- * ```
7186
- */
7187
- updateDocument(kbID: string, docID: string, data: UpdateDocumentRequest): Promise<DocumentResponse>;
7188
7232
  /**
7189
7233
  * 문서 목록 조회
7190
7234
  *
@@ -7285,6 +7329,11 @@ interface AISource {
7285
7329
  }
7286
7330
  interface AIChatResponse {
7287
7331
  content: string;
7332
+ /**
7333
+ * 추론 모델(Qwen3 reasoning, OpenAI o-series, DeepSeek-R1 등)의 사고 과정.
7334
+ * 최종 답변(`content`)과 분리되어 제공됩니다. 추론 모델이 아니면 비어 있습니다.
7335
+ */
7336
+ reasoning?: string;
7288
7337
  finishReason?: string;
7289
7338
  usage?: {
7290
7339
  promptTokens: number;
@@ -7296,9 +7345,30 @@ interface AIChatResponse {
7296
7345
  toolCalls?: AIToolCall[];
7297
7346
  sources?: AISource[];
7298
7347
  }
7348
+ /**
7349
+ * Agentic 검색의 한 단계 진행 상황. `chatStream({ agentic: true })` 시
7350
+ * `onSearching` 콜백으로 실시간 전달되어 "검색 중…" 진행 UI 를 구성할 수 있다.
7351
+ */
7352
+ interface AgenticSearchProgress {
7353
+ /** 'query_generation' = 검색어 생성 중, 'searching' = 검색 실행 중, 'complete' = 검색 종료 */
7354
+ phase: 'query_generation' | 'searching' | 'complete';
7355
+ /** 검색 라운드 (1~2). agentic 은 결과가 부족하면 2라운드까지 수행. */
7356
+ round?: number;
7357
+ /** 이 라운드에서 생성된 검색 쿼리들 (phase='searching'). */
7358
+ queries?: string[];
7359
+ /** phase='complete': 누적 결과 청크 수. */
7360
+ results?: number;
7361
+ /** phase='complete': 총 검색 라운드 수. 0 은 폴백(단일 키워드 검색)을 의미. */
7362
+ rounds?: number;
7363
+ }
7299
7364
  interface AIStreamChunk {
7300
7365
  type?: 'sources' | 'token' | 'searching' | 'tool_start' | 'tool_end' | 'heartbeat';
7301
7366
  content: string;
7367
+ /**
7368
+ * 추론 모델의 사고 과정 델타. 추론 구간의 청크는 `content`가 비어 있고
7369
+ * `reasoning`만 채워져 전달됩니다.
7370
+ */
7371
+ reasoning?: string;
7302
7372
  finishReason?: string;
7303
7373
  done: boolean;
7304
7374
  toolCalls?: AIToolCall[];
@@ -7309,6 +7379,7 @@ interface AIStreamChunk {
7309
7379
  result?: string;
7310
7380
  success?: boolean;
7311
7381
  durationMs?: number;
7382
+ searching?: AgenticSearchProgress;
7312
7383
  }
7313
7384
 
7314
7385
  /**
@@ -7352,6 +7423,7 @@ declare class AIAPI {
7352
7423
  * knowledgeBaseId: 'kb-id',
7353
7424
  * }, {
7354
7425
  * onSources: (sources) => console.log('참조:', sources),
7426
+ * onReasoning: (reasoning) => process.stdout.write(reasoning),
7355
7427
  * onToken: (content) => process.stdout.write(content),
7356
7428
  * onDone: () => console.log('\\n완료'),
7357
7429
  * onError: (error) => console.error('에러:', error)
@@ -7360,8 +7432,19 @@ declare class AIAPI {
7360
7432
  */
7361
7433
  chatStream(request: AIChatRequest, callbacks: {
7362
7434
  onSources?: (sources: AISource[]) => void;
7435
+ /**
7436
+ * 추론 모델의 사고 과정 델타. 추론 모델(Qwen3 reasoning, o-series 등)을
7437
+ * 사용할 때만 호출되며, 최종 답변은 `onToken`으로 별도 전달됩니다.
7438
+ */
7439
+ onReasoning?: (reasoning: string) => void;
7363
7440
  onToken?: (content: string) => void;
7364
7441
  onToolEvent?: (event: AIToolEvent) => void;
7442
+ /**
7443
+ * Agentic 검색(`agentic: true`) 진행 상황. agentic 검색이 검색어를
7444
+ * 생성하고 다중 라운드로 검색하는 각 단계마다 호출되어, "검색 중…"
7445
+ * 진행 UI 를 구성할 수 있다. agentic 미사용 시 호출되지 않는다.
7446
+ */
7447
+ onSearching?: (progress: AgenticSearchProgress) => void;
7365
7448
  onDone?: () => void;
7366
7449
  onError?: (error: string) => void;
7367
7450
  }): Promise<void>;
package/dist/index.js CHANGED
@@ -8050,6 +8050,15 @@ var KnowledgeAPI = class {
8050
8050
  * source_type: 'url',
8051
8051
  * source_url: 'https://example.com/help.html'
8052
8052
  * })
8053
+ *
8054
+ * // external_id 로 idempotent 동기화 (빌드 스크립트 등)
8055
+ * // 같은 external_id 로 다시 호출하면 기존 문서를 교체한다 (문서 id 유지).
8056
+ * await cb.knowledge.addDocument('kb-id', {
8057
+ * name: '블로그: 제목',
8058
+ * source_type: 'text',
8059
+ * content: '...',
8060
+ * external_id: 'blog/my-post-slug',
8061
+ * })
8053
8062
  * ```
8054
8063
  */
8055
8064
  async addDocument(kbID, data) {
@@ -8058,6 +8067,58 @@ var KnowledgeAPI = class {
8058
8067
  data
8059
8068
  );
8060
8069
  }
8070
+ /**
8071
+ * 문서 수정 (update/upsert)
8072
+ *
8073
+ * 기존 문서의 내용·이름·메타데이터를 교체합니다. **문서 id 는 그대로 유지**되므로
8074
+ * 검색 결과의 `document_id` 를 외부에서 참조(인용·캐시)해도 편집 후 깨지지 않습니다.
8075
+ * 보낸 필드만 교체되며, 내용/이름/메타데이터가 실제로 바뀌면 자동으로 재청킹·재색인됩니다.
8076
+ *
8077
+ * @param kbID - 지식 베이스 ID
8078
+ * @param docID - 문서 ID
8079
+ * @param data - 변경할 필드 (생략한 필드는 변경 없음)
8080
+ * @returns 수정된 문서 정보
8081
+ *
8082
+ * @example
8083
+ * ```typescript
8084
+ * // 내용만 교체 — document_id 는 그대로
8085
+ * const doc = await cb.knowledge.updateDocument('kb-id', 'doc-id', {
8086
+ * content: '갱신된 환불 정책...',
8087
+ * })
8088
+ *
8089
+ * // 이름 + 메타데이터 교체
8090
+ * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
8091
+ * name: 'FAQ (2026)',
8092
+ * metadata: { tag: 'faq', updated: '2026-05' },
8093
+ * })
8094
+ * ```
8095
+ */
8096
+ async updateDocument(kbID, docID, data) {
8097
+ return this.http.put(
8098
+ `/v1/public/knowledge-bases/${kbID}/documents/${docID}`,
8099
+ data
8100
+ );
8101
+ }
8102
+ /**
8103
+ * 파일로 문서 수정 (PDF / DOCX / text 파일 재업로드).
8104
+ *
8105
+ * [`addDocumentFromFile`](#addDocumentFromFile) 의 update 버전. 문서 id 는 유지됩니다.
8106
+ *
8107
+ * @param kbID - Knowledge Base ID
8108
+ * @param docID - 문서 ID
8109
+ * @param file - 새 파일. `File` (DOM) / `Blob` / `{ data, mimeType, name }` (Node) 모두 가능
8110
+ * @param options - name / metadata 오버라이드
8111
+ * @returns 수정된 문서 정보
8112
+ */
8113
+ async updateDocumentFromFile(kbID, docID, file, options) {
8114
+ const { data, mimeType } = await readFileInput(file);
8115
+ return this.updateDocument(kbID, docID, {
8116
+ name: options?.name,
8117
+ file_content: data,
8118
+ mime_type: mimeType,
8119
+ metadata: options?.metadata
8120
+ });
8121
+ }
8061
8122
  /**
8062
8123
  * 파일을 KB 에 추가 (PDF / DOCX / text 파일).
8063
8124
  *
@@ -8109,36 +8170,6 @@ var KnowledgeAPI = class {
8109
8170
  metadata: options?.metadata
8110
8171
  });
8111
8172
  }
8112
- /**
8113
- * 문서 수정 (재색인)
8114
- *
8115
- * `content` / `file_content` / `metadata` 중 하나라도 포함하면 전체 재색인이 일어나며
8116
- * 색인 토큰이 다시 과금됩니다. `name` 만 보내면 재색인 없이 라벨만 변경됩니다.
8117
- * 재색인 시 서버는 status='pending' 으로 즉시 응답하고 색인은 백그라운드로 진행됩니다
8118
- * (addDocument 와 동일) — get/listDocuments 로 'ready' 전환을 확인하세요.
8119
- *
8120
- * @param kbID - 지식 베이스 ID
8121
- * @param docID - 문서 ID
8122
- * @param data - 수정 요청 (모든 필드 옵셔널)
8123
- * @returns 수정된 문서 정보
8124
- *
8125
- * @example
8126
- * ```typescript
8127
- * // 내용 갱신 (전체 재색인 발생)
8128
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', {
8129
- * content: '환불은 구매 후 14일 이내에 가능합니다...'
8130
- * })
8131
- *
8132
- * // 이름만 변경 (재색인 없음)
8133
- * await cb.knowledge.updateDocument('kb-id', 'doc-id', { name: '환불 정책 v2' })
8134
- * ```
8135
- */
8136
- async updateDocument(kbID, docID, data) {
8137
- return this.http.put(
8138
- `/v1/public/knowledge-bases/${kbID}/documents/${docID}`,
8139
- data
8140
- );
8141
- }
8142
8173
  /**
8143
8174
  * 문서 목록 조회
8144
8175
  *
@@ -8232,6 +8263,7 @@ var AIAPI = class {
8232
8263
  * knowledgeBaseId: 'kb-id',
8233
8264
  * }, {
8234
8265
  * onSources: (sources) => console.log('참조:', sources),
8266
+ * onReasoning: (reasoning) => process.stdout.write(reasoning),
8235
8267
  * onToken: (content) => process.stdout.write(content),
8236
8268
  * onDone: () => console.log('\\n완료'),
8237
8269
  * onError: (error) => console.error('에러:', error)
@@ -8290,9 +8322,14 @@ var AIAPI = class {
8290
8322
  });
8291
8323
  continue;
8292
8324
  }
8293
- if (event.type === "heartbeat" || event.type === "searching") {
8325
+ if (event.type === "searching") {
8326
+ if (event.searching) callbacks.onSearching?.(event.searching);
8327
+ continue;
8328
+ }
8329
+ if (event.type === "heartbeat") {
8294
8330
  continue;
8295
8331
  }
8332
+ if (event.reasoning) callbacks.onReasoning?.(event.reasoning);
8296
8333
  if (event.content) callbacks.onToken?.(event.content);
8297
8334
  if (event.done) {
8298
8335
  callbacks.onDone?.();