@colineapp/kairo-core 0.1.0 → 0.1.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.
Files changed (3) hide show
  1. package/dist/index.d.ts +120 -82
  2. package/dist/index.js +231 -244
  3. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -1,134 +1,172 @@
1
1
  export declare const KAIRO_BASE_URL: "https://coline.app";
2
2
  export declare const KAIRO_OAUTH_PATHS: {
3
- readonly authorize: "/api/kairo/oauth/authorize";
4
- readonly token: "/api/kairo/oauth/token";
5
- readonly deviceAuthorize: "/api/kairo/oauth/device/authorize";
6
- readonly revoke: "/api/kairo/oauth/revoke";
7
- readonly agentStream: "/api/kairo/agent/stream";
8
- readonly models: "/api/kairo/models";
9
- };
10
- export declare const KAIRO_REQUIRED_SCOPES: readonly ["kairo.agent:stream", "kairo.models:read"];
3
+ readonly authorize: "/api/kairo/oauth/authorize";
4
+ readonly token: "/api/kairo/oauth/token";
5
+ readonly deviceAuthorize: "/api/kairo/oauth/device/authorize";
6
+ readonly revoke: "/api/kairo/oauth/revoke";
7
+ readonly agentStream: "/api/kairo/agent/stream";
8
+ readonly models: "/api/kairo/models";
9
+ };
10
+ export declare const KAIRO_REQUIRED_SCOPES: readonly [
11
+ "kairo.agent:stream",
12
+ "kairo.models:read",
13
+ ];
11
14
  export declare const KAIRO_DEFAULT_SCOPE: string;
12
- export declare const KAIRO_MODEL_IDS: readonly ["gpt-5-nano", "gpt-5-mini", "gpt-5", "gpt-5.1", "gpt-5.2", "grok-4-fast-reasoning", "grok-4-fast-non-reasoning", "deepseek-v3.2", "deepseek-v3.2-speciale", "kimi-k2-thinking"];
15
+ export declare const KAIRO_MODEL_IDS: readonly [
16
+ "gpt-5-nano",
17
+ "gpt-5-mini",
18
+ "gpt-5",
19
+ "gpt-5.1",
20
+ "gpt-5.2",
21
+ "claude-opus-4.6",
22
+ "claude-opus-4.5",
23
+ "claude-sonnet-4.5",
24
+ "grok-4-fast-reasoning",
25
+ "grok-4-fast-non-reasoning",
26
+ "deepseek-v3.2",
27
+ "deepseek-v3.2-speciale",
28
+ "kimi-k2-thinking",
29
+ ];
13
30
  export type KairoModelId = (typeof KAIRO_MODEL_IDS)[number];
14
31
  export declare const KAIRO_DEFAULT_MODEL: KairoModelId;
15
32
  export type KairoOauthErrorResponse = {
16
- error: string;
17
- error_description?: string;
18
- error_uri?: string;
33
+ error: string;
34
+ error_description?: string;
35
+ error_uri?: string;
19
36
  };
20
37
  export type KairoTokenResponse = {
21
- access_token: string;
22
- token_type: string;
23
- expires_in: number;
24
- scope?: string;
25
- refresh_token?: string;
38
+ access_token: string;
39
+ token_type: string;
40
+ expires_in: number;
41
+ scope?: string;
42
+ refresh_token?: string;
26
43
  };
27
44
  export type KairoDeviceAuthorizationResponse = {
28
- device_code: string;
29
- user_code: string;
30
- verification_uri: string;
31
- verification_uri_complete?: string;
32
- expires_in: number;
33
- interval?: number;
34
- scope?: string;
45
+ device_code: string;
46
+ user_code: string;
47
+ verification_uri: string;
48
+ verification_uri_complete?: string;
49
+ expires_in: number;
50
+ interval?: number;
51
+ scope?: string;
35
52
  };
36
53
  export type KairoRole = "system" | "user" | "model" | "function";
37
54
  export type KairoTextPart = {
38
- text: string;
55
+ text: string;
39
56
  };
40
57
  export type KairoInlineDataPart = {
41
- inlineData: {
58
+ inlineData:
59
+ | {
42
60
  mimeType: string;
43
61
  data: string;
44
- } | {
62
+ }
63
+ | {
45
64
  imageUrl: string;
46
- } | {
65
+ }
66
+ | {
47
67
  fileData: string;
48
68
  filename?: string;
49
- } | {
69
+ }
70
+ | {
50
71
  fileId: string;
51
72
  filename?: string;
52
- };
73
+ };
53
74
  };
54
75
  export type KairoFunctionCall = {
55
- id?: string;
56
- name: string;
57
- args: Record<string, unknown>;
58
- rawArguments?: string;
76
+ id?: string;
77
+ name: string;
78
+ args: Record<string, unknown>;
79
+ rawArguments?: string;
59
80
  };
60
81
  export type KairoFunctionCallPart = {
61
- functionCall: KairoFunctionCall;
82
+ functionCall: KairoFunctionCall;
62
83
  };
63
84
  export type KairoFunctionResponsePart = {
64
- functionResponse: {
65
- name: string;
66
- response: unknown;
67
- id?: string;
68
- };
85
+ functionResponse: {
86
+ name: string;
87
+ response: unknown;
88
+ id?: string;
89
+ };
69
90
  };
70
- export type KairoMessagePart = KairoTextPart | KairoInlineDataPart | KairoFunctionCallPart | KairoFunctionResponsePart;
91
+ export type KairoMessagePart =
92
+ | KairoTextPart
93
+ | KairoInlineDataPart
94
+ | KairoFunctionCallPart
95
+ | KairoFunctionResponsePart;
71
96
  export type KairoContent = {
72
- role: KairoRole;
73
- parts: KairoMessagePart[];
97
+ role: KairoRole;
98
+ parts: KairoMessagePart[];
74
99
  };
75
100
  export type KairoAgentStreamRequest = {
76
- contents: KairoContent[];
77
- modelType?: KairoModelId | string;
78
- reasoningLevel?: number;
79
- thinkingBudget?: number;
80
- traceId?: string;
101
+ contents: KairoContent[];
102
+ modelType?: KairoModelId | string;
103
+ reasoningLevel?: number;
104
+ thinkingBudget?: number;
105
+ traceId?: string;
81
106
  } & Record<string, unknown>;
82
107
  export type KairoOauthErrorDetails = {
83
- code: string;
84
- description: string | null;
85
- uri: string | null;
108
+ code: string;
109
+ description: string | null;
110
+ uri: string | null;
86
111
  };
87
112
  export type KairoErrorOptions = {
88
- message: string;
89
- status: number | null;
90
- code: string;
91
- description?: string | null;
92
- details?: unknown;
113
+ message: string;
114
+ status: number | null;
115
+ code: string;
116
+ description?: string | null;
117
+ details?: unknown;
93
118
  };
94
119
  export declare class KairoError extends Error {
95
- readonly status: number | null;
96
- readonly code: string;
97
- readonly description: string | null;
98
- readonly details: unknown;
99
- constructor(options: KairoErrorOptions);
120
+ readonly status: number | null;
121
+ readonly code: string;
122
+ readonly description: string | null;
123
+ readonly details: unknown;
124
+ constructor(options: KairoErrorOptions);
100
125
  }
101
126
  export declare function resolveBaseUrl(baseUrl?: string): string;
102
- export declare function buildKairoUrl(baseUrl: string | undefined, path: string): string;
127
+ export declare function buildKairoUrl(
128
+ baseUrl: string | undefined,
129
+ path: string,
130
+ ): string;
103
131
  export declare const KAIRO_TOKEN_EXPIRY_SAFETY_MS = 30000;
104
- export declare function computeExpiresAt(expiresInSeconds: number, nowMs?: number, safetyMs?: number): number;
132
+ export declare function computeExpiresAt(
133
+ expiresInSeconds: number,
134
+ nowMs?: number,
135
+ safetyMs?: number,
136
+ ): number;
105
137
  export declare function isExpired(expiresAt: number, nowMs?: number): boolean;
106
138
  export declare function assertOk(response: Response): Promise<Response>;
107
139
  export type KairoSseEvent = {
108
- raw: string;
109
- data: unknown;
110
- event: string | null;
111
- parsed: boolean;
112
- };
113
- export declare function iterateSse(response: Response): AsyncGenerator<KairoSseEvent>;
140
+ raw: string;
141
+ data: unknown;
142
+ event: string | null;
143
+ parsed: boolean;
144
+ };
145
+ export declare function iterateSse(
146
+ response: Response,
147
+ ): AsyncGenerator<KairoSseEvent>;
114
148
  export declare function extractTextChunks(data: unknown): string[];
115
- export declare function accumulateText(events: AsyncIterable<KairoSseEvent>): Promise<string>;
149
+ export declare function accumulateText(
150
+ events: AsyncIterable<KairoSseEvent>,
151
+ ): Promise<string>;
116
152
  export type KairoTokenSet = {
117
- accessToken: string;
118
- refreshToken: string | null;
119
- expiresAt: number;
120
- scope: string | null;
121
- tokenType: string;
153
+ accessToken: string;
154
+ refreshToken: string | null;
155
+ expiresAt: number;
156
+ scope: string | null;
157
+ tokenType: string;
122
158
  };
123
159
  export declare function toTokenSet(response: KairoTokenResponse): KairoTokenSet;
124
160
  export type KairoModelListOptions = {
125
- baseUrl?: string;
126
- fetch?: typeof fetch;
127
- signal?: AbortSignal;
161
+ baseUrl?: string;
162
+ fetch?: typeof fetch;
163
+ signal?: AbortSignal;
128
164
  };
129
165
  export type KairoModelListResponse = {
130
- defaultModel: string;
131
- models: string[];
166
+ defaultModel: string;
167
+ models: string[];
132
168
  };
133
- export declare function listKairoModels(options?: KairoModelListOptions): Promise<KairoModelListResponse>;
134
- //# sourceMappingURL=index.d.ts.map
169
+ export declare function listKairoModels(
170
+ options?: KairoModelListOptions,
171
+ ): Promise<KairoModelListResponse>;
172
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,295 +1,282 @@
1
- import { createParser, } from "eventsource-parser";
1
+ import { createParser } from "eventsource-parser";
2
2
  export const KAIRO_BASE_URL = "https://coline.app";
3
3
  export const KAIRO_OAUTH_PATHS = {
4
- authorize: "/api/kairo/oauth/authorize",
5
- token: "/api/kairo/oauth/token",
6
- deviceAuthorize: "/api/kairo/oauth/device/authorize",
7
- revoke: "/api/kairo/oauth/revoke",
8
- agentStream: "/api/kairo/agent/stream",
9
- models: "/api/kairo/models",
4
+ authorize: "/api/kairo/oauth/authorize",
5
+ token: "/api/kairo/oauth/token",
6
+ deviceAuthorize: "/api/kairo/oauth/device/authorize",
7
+ revoke: "/api/kairo/oauth/revoke",
8
+ agentStream: "/api/kairo/agent/stream",
9
+ models: "/api/kairo/models",
10
10
  };
11
11
  export const KAIRO_REQUIRED_SCOPES = [
12
- "kairo.agent:stream",
13
- "kairo.models:read",
12
+ "kairo.agent:stream",
13
+ "kairo.models:read",
14
14
  ];
15
15
  export const KAIRO_DEFAULT_SCOPE = KAIRO_REQUIRED_SCOPES.join(" ");
16
16
  export const KAIRO_MODEL_IDS = [
17
- "gpt-5-nano",
18
- "gpt-5-mini",
19
- "gpt-5",
20
- "gpt-5.1",
21
- "gpt-5.2",
22
- "grok-4-fast-reasoning",
23
- "grok-4-fast-non-reasoning",
24
- "deepseek-v3.2",
25
- "deepseek-v3.2-speciale",
26
- "kimi-k2-thinking",
17
+ "gpt-5-nano",
18
+ "gpt-5-mini",
19
+ "gpt-5",
20
+ "gpt-5.1",
21
+ "gpt-5.2",
22
+ "claude-opus-4.6",
23
+ "claude-opus-4.5",
24
+ "claude-sonnet-4.5",
25
+ "grok-4-fast-reasoning",
26
+ "grok-4-fast-non-reasoning",
27
+ "deepseek-v3.2",
28
+ "deepseek-v3.2-speciale",
29
+ "kimi-k2-thinking",
27
30
  ];
28
31
  export const KAIRO_DEFAULT_MODEL = "gpt-5.2";
29
32
  export class KairoError extends Error {
30
- status;
31
- code;
32
- description;
33
- details;
34
- constructor(options) {
35
- super(options.message);
36
- this.name = "KairoError";
37
- this.status = options.status;
38
- this.code = options.code;
39
- this.description = options.description ?? null;
40
- this.details = options.details ?? null;
41
- }
33
+ status;
34
+ code;
35
+ description;
36
+ details;
37
+ constructor(options) {
38
+ super(options.message);
39
+ this.name = "KairoError";
40
+ this.status = options.status;
41
+ this.code = options.code;
42
+ this.description = options.description ?? null;
43
+ this.details = options.details ?? null;
44
+ }
42
45
  }
43
46
  function isRecord(value) {
44
- return typeof value === "object" && value !== null;
47
+ return typeof value === "object" && value !== null;
45
48
  }
46
49
  function readOauthErrorDetails(value) {
47
- if (!isRecord(value))
48
- return null;
49
- const code = typeof value.error === "string" ? value.error : null;
50
- if (!code)
51
- return null;
52
- const description = typeof value.error_description === "string"
53
- ? value.error_description
54
- : null;
55
- const uri = typeof value.error_uri === "string" ? value.error_uri : null;
56
- return { code, description, uri };
50
+ if (!isRecord(value)) return null;
51
+ const code = typeof value.error === "string" ? value.error : null;
52
+ if (!code) return null;
53
+ const description =
54
+ typeof value.error_description === "string"
55
+ ? value.error_description
56
+ : null;
57
+ const uri = typeof value.error_uri === "string" ? value.error_uri : null;
58
+ return { code, description, uri };
57
59
  }
58
60
  export function resolveBaseUrl(baseUrl) {
59
- if (!baseUrl)
60
- return KAIRO_BASE_URL;
61
- const trimmed = baseUrl.trim();
62
- return trimmed.length > 0 ? trimmed : KAIRO_BASE_URL;
61
+ if (!baseUrl) return KAIRO_BASE_URL;
62
+ const trimmed = baseUrl.trim();
63
+ return trimmed.length > 0 ? trimmed : KAIRO_BASE_URL;
63
64
  }
64
65
  function resolveFetch(override) {
65
- const fetchImpl = override ?? globalThis.fetch;
66
- if (!fetchImpl) {
67
- throw new KairoError({
68
- message: "No fetch implementation is available",
69
- status: null,
70
- code: "missing_fetch",
71
- });
72
- }
73
- return fetchImpl;
66
+ const fetchImpl = override ?? globalThis.fetch;
67
+ if (!fetchImpl) {
68
+ throw new KairoError({
69
+ message: "No fetch implementation is available",
70
+ status: null,
71
+ code: "missing_fetch",
72
+ });
73
+ }
74
+ return fetchImpl;
74
75
  }
75
76
  export function buildKairoUrl(baseUrl, path) {
76
- const origin = resolveBaseUrl(baseUrl);
77
- return new URL(path, origin).toString();
77
+ const origin = resolveBaseUrl(baseUrl);
78
+ return new URL(path, origin).toString();
78
79
  }
79
80
  export const KAIRO_TOKEN_EXPIRY_SAFETY_MS = 30_000;
80
- export function computeExpiresAt(expiresInSeconds, nowMs = Date.now(), safetyMs = KAIRO_TOKEN_EXPIRY_SAFETY_MS) {
81
- const ttlMs = Math.max(0, expiresInSeconds * 1000 - safetyMs);
82
- return nowMs + ttlMs;
81
+ export function computeExpiresAt(
82
+ expiresInSeconds,
83
+ nowMs = Date.now(),
84
+ safetyMs = KAIRO_TOKEN_EXPIRY_SAFETY_MS,
85
+ ) {
86
+ const ttlMs = Math.max(0, expiresInSeconds * 1000 - safetyMs);
87
+ return nowMs + ttlMs;
83
88
  }
84
89
  export function isExpired(expiresAt, nowMs = Date.now()) {
85
- return expiresAt <= nowMs;
90
+ return expiresAt <= nowMs;
86
91
  }
87
92
  export async function assertOk(response) {
88
- if (response.ok)
89
- return response;
90
- let payload = null;
91
- try {
92
- payload = await response.clone().json();
93
- }
94
- catch {
95
- payload = null;
96
- }
97
- const oauthError = readOauthErrorDetails(payload);
98
- const message = oauthError?.description
99
- ? oauthError.description
100
- : oauthError?.code
101
- ? oauthError.code
102
- : `Request failed with status ${response.status}`;
103
- throw new KairoError({
104
- message,
105
- status: response.status,
106
- code: oauthError?.code ?? "http_error",
107
- description: oauthError?.description ?? null,
108
- details: payload,
109
- });
93
+ if (response.ok) return response;
94
+ let payload = null;
95
+ try {
96
+ payload = await response.clone().json();
97
+ } catch {
98
+ payload = null;
99
+ }
100
+ const oauthError = readOauthErrorDetails(payload);
101
+ const message = oauthError?.description
102
+ ? oauthError.description
103
+ : oauthError?.code
104
+ ? oauthError.code
105
+ : `Request failed with status ${response.status}`;
106
+ throw new KairoError({
107
+ message,
108
+ status: response.status,
109
+ code: oauthError?.code ?? "http_error",
110
+ description: oauthError?.description ?? null,
111
+ details: payload,
112
+ });
110
113
  }
111
114
  function safeParseJson(raw) {
112
- try {
113
- return {
114
- parsed: true,
115
- value: JSON.parse(raw),
116
- };
117
- }
118
- catch {
119
- return {
120
- parsed: false,
121
- value: raw,
122
- };
123
- }
115
+ try {
116
+ return {
117
+ parsed: true,
118
+ value: JSON.parse(raw),
119
+ };
120
+ } catch {
121
+ return {
122
+ parsed: false,
123
+ value: raw,
124
+ };
125
+ }
124
126
  }
125
127
  function deriveEventName(parsed, fallback) {
126
- if (isRecord(parsed) && typeof parsed.event === "string") {
127
- return parsed.event;
128
- }
129
- return fallback ?? null;
128
+ if (isRecord(parsed) && typeof parsed.event === "string") {
129
+ return parsed.event;
130
+ }
131
+ return fallback ?? null;
130
132
  }
131
133
  export async function* iterateSse(response) {
132
- if (!response.body) {
133
- throw new KairoError({
134
- message: "Streaming response has no body",
135
- status: response.status,
136
- code: "missing_stream_body",
137
- });
134
+ if (!response.body) {
135
+ throw new KairoError({
136
+ message: "Streaming response has no body",
137
+ status: response.status,
138
+ code: "missing_stream_body",
139
+ });
140
+ }
141
+ const reader = response.body.getReader();
142
+ const decoder = new TextDecoder();
143
+ const queue = [];
144
+ let pendingResolve = null;
145
+ let done = false;
146
+ let pumpError = null;
147
+ const push = (event) => {
148
+ if (pendingResolve) {
149
+ const resolve = pendingResolve;
150
+ pendingResolve = null;
151
+ resolve(event);
152
+ return;
138
153
  }
139
- const reader = response.body.getReader();
140
- const decoder = new TextDecoder();
141
- const queue = [];
142
- let pendingResolve = null;
143
- let done = false;
144
- let pumpError = null;
145
- const push = (event) => {
146
- if (pendingResolve) {
147
- const resolve = pendingResolve;
148
- pendingResolve = null;
149
- resolve(event);
150
- return;
151
- }
152
- if (event) {
153
- queue.push(event);
154
- }
155
- else {
156
- done = true;
157
- }
158
- };
159
- const onParseEvent = (event) => {
160
- const parsed = safeParseJson(event.data);
161
- const eventName = deriveEventName(parsed.value, event.event);
162
- push({
163
- raw: event.data,
164
- data: parsed.value,
165
- event: eventName,
166
- parsed: parsed.parsed,
167
- });
168
- };
169
- const parser = createParser({
170
- onEvent: onParseEvent,
171
- onError: (_error) => {
172
- },
154
+ if (event) {
155
+ queue.push(event);
156
+ } else {
157
+ done = true;
158
+ }
159
+ };
160
+ const onParseEvent = (event) => {
161
+ const parsed = safeParseJson(event.data);
162
+ const eventName = deriveEventName(parsed.value, event.event);
163
+ push({
164
+ raw: event.data,
165
+ data: parsed.value,
166
+ event: eventName,
167
+ parsed: parsed.parsed,
173
168
  });
174
- const pump = (async () => {
175
- try {
176
- while (true) {
177
- const { done: readerDone, value } = await reader.read();
178
- if (readerDone)
179
- break;
180
- if (!value)
181
- continue;
182
- parser.feed(decoder.decode(value, { stream: true }));
183
- }
184
- const tail = decoder.decode();
185
- if (tail) {
186
- parser.feed(tail);
187
- }
188
- }
189
- catch (error) {
190
- pumpError = error;
191
- }
192
- finally {
193
- try {
194
- reader.releaseLock();
195
- }
196
- catch {
197
- }
198
- push(null);
199
- }
200
- })();
169
+ };
170
+ const parser = createParser({
171
+ onEvent: onParseEvent,
172
+ onError: (_error) => {},
173
+ });
174
+ const pump = (async () => {
201
175
  try {
202
- while (true) {
203
- if (queue.length > 0) {
204
- const next = queue.shift();
205
- if (next) {
206
- yield next;
207
- continue;
208
- }
209
- }
210
- if (done)
211
- break;
212
- const awaited = await new Promise((resolve) => {
213
- pendingResolve = resolve;
214
- });
215
- if (!awaited)
216
- break;
217
- yield awaited;
218
- }
219
- }
220
- finally {
221
- await pump;
176
+ while (true) {
177
+ const { done: readerDone, value } = await reader.read();
178
+ if (readerDone) break;
179
+ if (!value) continue;
180
+ parser.feed(decoder.decode(value, { stream: true }));
181
+ }
182
+ const tail = decoder.decode();
183
+ if (tail) {
184
+ parser.feed(tail);
185
+ }
186
+ } catch (error) {
187
+ pumpError = error;
188
+ } finally {
189
+ try {
190
+ reader.releaseLock();
191
+ } catch {}
192
+ push(null);
222
193
  }
223
- if (pumpError) {
224
- throw pumpError;
194
+ })();
195
+ try {
196
+ while (true) {
197
+ if (queue.length > 0) {
198
+ const next = queue.shift();
199
+ if (next) {
200
+ yield next;
201
+ continue;
202
+ }
203
+ }
204
+ if (done) break;
205
+ const awaited = await new Promise((resolve) => {
206
+ pendingResolve = resolve;
207
+ });
208
+ if (!awaited) break;
209
+ yield awaited;
225
210
  }
211
+ } finally {
212
+ await pump;
213
+ }
214
+ if (pumpError) {
215
+ throw pumpError;
216
+ }
226
217
  }
227
218
  function readPartsFromCandidate(value) {
228
- if (!isRecord(value))
229
- return [];
230
- const parts = value.parts;
231
- return Array.isArray(parts) ? parts : [];
219
+ if (!isRecord(value)) return [];
220
+ const parts = value.parts;
221
+ return Array.isArray(parts) ? parts : [];
232
222
  }
233
223
  function extractTextFromPart(part) {
234
- if (!isRecord(part))
235
- return [];
236
- if (typeof part.text === "string" && part.text.length > 0) {
237
- return [part.text];
238
- }
239
- const type = typeof part.type === "string" ? part.type : null;
240
- if (!type)
241
- return [];
242
- if (type === "output_text" || type === "input_text") {
243
- return typeof part.text === "string" && part.text.length > 0
244
- ? [part.text]
245
- : [];
246
- }
247
- return [];
224
+ if (!isRecord(part)) return [];
225
+ if (typeof part.text === "string" && part.text.length > 0) {
226
+ return [part.text];
227
+ }
228
+ const type = typeof part.type === "string" ? part.type : null;
229
+ if (!type) return [];
230
+ if (type === "output_text" || type === "input_text") {
231
+ return typeof part.text === "string" && part.text.length > 0
232
+ ? [part.text]
233
+ : [];
234
+ }
235
+ return [];
248
236
  }
249
237
  export function extractTextChunks(data) {
250
- if (!isRecord(data))
251
- return [];
252
- const chunks = [];
253
- if (typeof data.text === "string" && data.text.length > 0) {
254
- chunks.push(data.text);
255
- }
256
- const candidate = data.candidate_content;
257
- const parts = readPartsFromCandidate(candidate);
258
- for (const part of parts) {
259
- chunks.push(...extractTextFromPart(part));
260
- }
261
- return chunks;
238
+ if (!isRecord(data)) return [];
239
+ const chunks = [];
240
+ if (typeof data.text === "string" && data.text.length > 0) {
241
+ chunks.push(data.text);
242
+ }
243
+ const candidate = data.candidate_content;
244
+ const parts = readPartsFromCandidate(candidate);
245
+ for (const part of parts) {
246
+ chunks.push(...extractTextFromPart(part));
247
+ }
248
+ return chunks;
262
249
  }
263
250
  export async function accumulateText(events) {
264
- let text = "";
265
- for await (const event of events) {
266
- const chunks = extractTextChunks(event.data);
267
- for (const chunk of chunks) {
268
- text += chunk;
269
- }
251
+ let text = "";
252
+ for await (const event of events) {
253
+ const chunks = extractTextChunks(event.data);
254
+ for (const chunk of chunks) {
255
+ text += chunk;
270
256
  }
271
- return text;
257
+ }
258
+ return text;
272
259
  }
273
260
  export function toTokenSet(response) {
274
- return {
275
- accessToken: response.access_token,
276
- refreshToken: response.refresh_token ?? null,
277
- expiresAt: computeExpiresAt(response.expires_in),
278
- scope: response.scope ?? null,
279
- tokenType: response.token_type,
280
- };
261
+ return {
262
+ accessToken: response.access_token,
263
+ refreshToken: response.refresh_token ?? null,
264
+ expiresAt: computeExpiresAt(response.expires_in),
265
+ scope: response.scope ?? null,
266
+ tokenType: response.token_type,
267
+ };
281
268
  }
282
269
  export async function listKairoModels(options = {}) {
283
- const fetchImpl = resolveFetch(options.fetch);
284
- const url = buildKairoUrl(options.baseUrl, KAIRO_OAUTH_PATHS.models);
285
- const response = await fetchImpl(url, {
286
- method: "GET",
287
- headers: {
288
- Accept: "application/json",
289
- },
290
- signal: options.signal,
291
- });
292
- await assertOk(response);
293
- return (await response.json());
270
+ const fetchImpl = resolveFetch(options.fetch);
271
+ const url = buildKairoUrl(options.baseUrl, KAIRO_OAUTH_PATHS.models);
272
+ const response = await fetchImpl(url, {
273
+ method: "GET",
274
+ headers: {
275
+ Accept: "application/json",
276
+ },
277
+ signal: options.signal,
278
+ });
279
+ await assertOk(response);
280
+ return await response.json();
294
281
  }
295
- //# sourceMappingURL=index.js.map
282
+ //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@colineapp/kairo-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Core types and utilities for the Coline Kairo SDK.",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Coline Technologies, Inc.",