@onyx.dev/onyx-database 1.1.0 → 2.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/README.md +120 -0
- package/dist/{aggregates-DodZNu9-.d.cts → aggregates-BJT5DGGX.d.cts} +308 -1
- package/dist/{aggregates-DodZNu9-.d.ts → aggregates-BJT5DGGX.d.ts} +308 -1
- package/dist/edge.cjs +267 -11
- package/dist/edge.cjs.map +1 -1
- package/dist/edge.d.cts +2 -2
- package/dist/edge.d.ts +2 -2
- package/dist/edge.js +267 -11
- package/dist/edge.js.map +1 -1
- package/dist/gen/cli/generate.cjs +269 -11
- package/dist/gen/cli/generate.cjs.map +1 -1
- package/dist/index.cjs +269 -11
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +269 -11
- package/dist/index.js.map +1 -1
- package/dist/schema/cli/schema.cjs +271 -11
- package/dist/schema/cli/schema.cjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as OnyxFacade } from './aggregates-
|
|
2
|
-
export {
|
|
1
|
+
import { O as OnyxFacade } from './aggregates-BJT5DGGX.cjs';
|
|
2
|
+
export { s as AiChatClient, l as AiChatCompletionChoice, p as AiChatCompletionChunk, o as AiChatCompletionChunkChoice, n as AiChatCompletionChunkDelta, j as AiChatCompletionRequest, m as AiChatCompletionResponse, q as AiChatCompletionStream, k as AiChatCompletionUsage, f as AiChatMessage, r as AiChatOptions, c as AiChatRole, y as AiClient, x as AiErrorResponse, w as AiModel, v as AiModelsResponse, A as AiRequestOptions, t as AiScriptApprovalRequest, u as AiScriptApprovalResponse, h as AiTool, e as AiToolCall, d as AiToolCallFunction, i as AiToolChoice, g as AiToolFunction, a8 as FetchImpl, a7 as FetchResponse, F as FullTextQuery, ah as ICascadeBuilder, ai as ICascadeRelationshipBuilder, ae as IConditionBuilder, I as IOnyxDatabase, af as IQueryBuilder, ag as ISaveBuilder, a3 as LogicalOperator, b as OnyxConfig, a6 as OnyxDocument, aa as QueryCondition, a9 as QueryCriteria, a2 as QueryCriteriaOperator, ad as QueryPage, Q as QueryResults, a as QueryResultsPromise, R as RetryOptions, H as SchemaAttribute, Y as SchemaAttributeChange, D as SchemaDataType, a1 as SchemaDiff, P as SchemaEntity, V as SchemaHistoryEntry, G as SchemaIdentifier, E as SchemaIdentifierGenerator, K as SchemaIndex, Z as SchemaIndexChange, J as SchemaIndexType, L as SchemaResolver, _ as SchemaResolverChange, U as SchemaRevision, T as SchemaRevisionMetadata, a0 as SchemaTableDiff, N as SchemaTrigger, $ as SchemaTriggerChange, M as SchemaTriggerEvent, W as SchemaUpsertRequest, X as SchemaValidationResult, S as SecretMetadata, z as SecretRecord, C as SecretSaveRequest, B as SecretsListResponse, ab as SelectQuery, a4 as Sort, a5 as StreamAction, ac as UpdateQuery, aj as asc, aJ as avg, ar as between, aB as contains, aC as containsIgnoreCase, aL as count, ak as desc, al as eq, as as gt, at as gte, an as inOp, aH as isNull, az as like, aS as lower, au as lt, av as lte, aw as matches, aN as max, aQ as median, aM as min, am as neq, aD as notContains, aE as notContainsIgnoreCase, ap as notIn, aA as notLike, ay as notMatches, aI as notNull, aG as notStartsWith, aq as notWithin, aV as percentile, aU as replace, ax as search, aF as startsWith, aO as std, aT as substring, aK as sum, aR as upper, aP as variance, ao as within } from './aggregates-BJT5DGGX.cjs';
|
|
3
3
|
|
|
4
4
|
declare const onyx: OnyxFacade;
|
|
5
5
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { O as OnyxFacade } from './aggregates-
|
|
2
|
-
export {
|
|
1
|
+
import { O as OnyxFacade } from './aggregates-BJT5DGGX.js';
|
|
2
|
+
export { s as AiChatClient, l as AiChatCompletionChoice, p as AiChatCompletionChunk, o as AiChatCompletionChunkChoice, n as AiChatCompletionChunkDelta, j as AiChatCompletionRequest, m as AiChatCompletionResponse, q as AiChatCompletionStream, k as AiChatCompletionUsage, f as AiChatMessage, r as AiChatOptions, c as AiChatRole, y as AiClient, x as AiErrorResponse, w as AiModel, v as AiModelsResponse, A as AiRequestOptions, t as AiScriptApprovalRequest, u as AiScriptApprovalResponse, h as AiTool, e as AiToolCall, d as AiToolCallFunction, i as AiToolChoice, g as AiToolFunction, a8 as FetchImpl, a7 as FetchResponse, F as FullTextQuery, ah as ICascadeBuilder, ai as ICascadeRelationshipBuilder, ae as IConditionBuilder, I as IOnyxDatabase, af as IQueryBuilder, ag as ISaveBuilder, a3 as LogicalOperator, b as OnyxConfig, a6 as OnyxDocument, aa as QueryCondition, a9 as QueryCriteria, a2 as QueryCriteriaOperator, ad as QueryPage, Q as QueryResults, a as QueryResultsPromise, R as RetryOptions, H as SchemaAttribute, Y as SchemaAttributeChange, D as SchemaDataType, a1 as SchemaDiff, P as SchemaEntity, V as SchemaHistoryEntry, G as SchemaIdentifier, E as SchemaIdentifierGenerator, K as SchemaIndex, Z as SchemaIndexChange, J as SchemaIndexType, L as SchemaResolver, _ as SchemaResolverChange, U as SchemaRevision, T as SchemaRevisionMetadata, a0 as SchemaTableDiff, N as SchemaTrigger, $ as SchemaTriggerChange, M as SchemaTriggerEvent, W as SchemaUpsertRequest, X as SchemaValidationResult, S as SecretMetadata, z as SecretRecord, C as SecretSaveRequest, B as SecretsListResponse, ab as SelectQuery, a4 as Sort, a5 as StreamAction, ac as UpdateQuery, aj as asc, aJ as avg, ar as between, aB as contains, aC as containsIgnoreCase, aL as count, ak as desc, al as eq, as as gt, at as gte, an as inOp, aH as isNull, az as like, aS as lower, au as lt, av as lte, aw as matches, aN as max, aQ as median, aM as min, am as neq, aD as notContains, aE as notContainsIgnoreCase, ap as notIn, aA as notLike, ay as notMatches, aI as notNull, aG as notStartsWith, aq as notWithin, aV as percentile, aU as replace, ax as search, aF as startsWith, aO as std, aT as substring, aK as sum, aR as upper, aP as variance, ao as within } from './aggregates-BJT5DGGX.js';
|
|
3
3
|
|
|
4
4
|
declare const onyx: OnyxFacade;
|
|
5
5
|
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
// src/config/defaults.ts
|
|
2
2
|
var DEFAULT_BASE_URL = "https://api.onyx.dev";
|
|
3
|
+
var DEFAULT_AI_BASE_URL = "https://ai.onyx.dev";
|
|
4
|
+
var DEFAULT_AI_MODEL = "onyx";
|
|
3
5
|
var sanitizeBaseUrl = (u) => u.replace(/\/+$/, "");
|
|
4
6
|
|
|
5
7
|
// src/errors/config-error.ts
|
|
@@ -58,6 +60,8 @@ function readEnv(targetId) {
|
|
|
58
60
|
if (targetId && envId !== targetId) return {};
|
|
59
61
|
const res = dropUndefined({
|
|
60
62
|
baseUrl: pick("ONYX_DATABASE_BASE_URL"),
|
|
63
|
+
aiBaseUrl: pick("ONYX_AI_BASE_URL"),
|
|
64
|
+
defaultModel: pick("ONYX_DEFAULT_MODEL"),
|
|
61
65
|
databaseId: envId,
|
|
62
66
|
apiKey: pick("ONYX_DATABASE_API_KEY"),
|
|
63
67
|
apiSecret: pick("ONYX_DATABASE_API_SECRET")
|
|
@@ -194,6 +198,8 @@ async function resolveConfig(input) {
|
|
|
194
198
|
}
|
|
195
199
|
const merged = {
|
|
196
200
|
baseUrl: DEFAULT_BASE_URL,
|
|
201
|
+
aiBaseUrl: DEFAULT_AI_BASE_URL,
|
|
202
|
+
defaultModel: DEFAULT_AI_MODEL,
|
|
197
203
|
...dropUndefined(home),
|
|
198
204
|
...dropUndefined(project),
|
|
199
205
|
...dropUndefined(cfgPath),
|
|
@@ -202,6 +208,8 @@ async function resolveConfig(input) {
|
|
|
202
208
|
};
|
|
203
209
|
dbg("merged (pre-validate):", mask(merged));
|
|
204
210
|
const baseUrl = sanitizeBaseUrl(merged.baseUrl ?? DEFAULT_BASE_URL);
|
|
211
|
+
const aiBaseUrl = sanitizeBaseUrl(merged.aiBaseUrl ?? DEFAULT_AI_BASE_URL);
|
|
212
|
+
const defaultModel = typeof merged.defaultModel === "string" && merged.defaultModel.trim() ? merged.defaultModel.trim() : DEFAULT_AI_MODEL;
|
|
205
213
|
const databaseId = merged.databaseId ?? "";
|
|
206
214
|
const apiKey = merged.apiKey ?? "";
|
|
207
215
|
const apiSecret = merged.apiSecret ?? "";
|
|
@@ -237,6 +245,8 @@ async function resolveConfig(input) {
|
|
|
237
245
|
}
|
|
238
246
|
const resolved = {
|
|
239
247
|
baseUrl,
|
|
248
|
+
aiBaseUrl,
|
|
249
|
+
defaultModel,
|
|
240
250
|
databaseId,
|
|
241
251
|
apiKey,
|
|
242
252
|
apiSecret,
|
|
@@ -247,6 +257,8 @@ async function resolveConfig(input) {
|
|
|
247
257
|
};
|
|
248
258
|
const source = {
|
|
249
259
|
databaseId: input?.databaseId ? "explicit config" : env.databaseId ? "env" : cfgPath.databaseId ? "env ONYX_CONFIG_PATH" : project.databaseId ? "project file" : home.databaseId ? "home profile" : "unknown",
|
|
260
|
+
aiBaseUrl: input?.aiBaseUrl ? "explicit config" : env.aiBaseUrl ? "env" : cfgPath.aiBaseUrl ? "env ONYX_CONFIG_PATH" : project.aiBaseUrl ? "project file" : home.aiBaseUrl ? "home profile" : "default",
|
|
261
|
+
defaultModel: input?.defaultModel ? "explicit config" : env.defaultModel ? "env" : cfgPath.defaultModel ? "env ONYX_CONFIG_PATH" : project.defaultModel ? "project file" : home.defaultModel ? "home profile" : "default",
|
|
250
262
|
apiKey: input?.apiKey ? "explicit config" : env.apiKey ? "env" : cfgPath.apiKey ? "env ONYX_CONFIG_PATH" : project.apiKey ? "project file" : home.apiKey ? "home profile" : "unknown",
|
|
251
263
|
apiSecret: input?.apiSecret ? "explicit config" : env.apiSecret ? "env" : cfgPath.apiSecret ? "env ONYX_CONFIG_PATH" : project.apiSecret ? "project file" : home.apiSecret ? "home profile" : "unknown"
|
|
252
264
|
};
|
|
@@ -1264,38 +1276,69 @@ var OnyxDatabaseImpl = class {
|
|
|
1264
1276
|
cfgPromise;
|
|
1265
1277
|
resolved = null;
|
|
1266
1278
|
http = null;
|
|
1279
|
+
aiHttp = null;
|
|
1267
1280
|
streams = /* @__PURE__ */ new Set();
|
|
1268
1281
|
requestLoggingEnabled;
|
|
1269
1282
|
responseLoggingEnabled;
|
|
1270
1283
|
defaultPartition;
|
|
1284
|
+
ai;
|
|
1271
1285
|
constructor(config, resolveConfigWithCache) {
|
|
1272
1286
|
this.requestLoggingEnabled = !!config?.requestLoggingEnabled;
|
|
1273
1287
|
this.responseLoggingEnabled = !!config?.responseLoggingEnabled;
|
|
1274
1288
|
this.defaultPartition = config?.partition;
|
|
1275
1289
|
this.cfgPromise = resolveConfigWithCache(config);
|
|
1290
|
+
this.ai = this.createAiFacade();
|
|
1276
1291
|
}
|
|
1277
|
-
async
|
|
1292
|
+
async resolveConfig() {
|
|
1278
1293
|
if (!this.resolved) {
|
|
1279
1294
|
this.resolved = await this.cfgPromise;
|
|
1280
1295
|
}
|
|
1296
|
+
return this.resolved;
|
|
1297
|
+
}
|
|
1298
|
+
async ensureClient() {
|
|
1299
|
+
const cfg = await this.resolveConfig();
|
|
1281
1300
|
if (!this.http) {
|
|
1282
1301
|
this.http = new HttpClient({
|
|
1283
|
-
baseUrl:
|
|
1284
|
-
apiKey:
|
|
1285
|
-
apiSecret:
|
|
1286
|
-
fetchImpl:
|
|
1302
|
+
baseUrl: cfg.baseUrl,
|
|
1303
|
+
apiKey: cfg.apiKey,
|
|
1304
|
+
apiSecret: cfg.apiSecret,
|
|
1305
|
+
fetchImpl: cfg.fetch,
|
|
1287
1306
|
requestLoggingEnabled: this.requestLoggingEnabled,
|
|
1288
1307
|
responseLoggingEnabled: this.responseLoggingEnabled,
|
|
1289
|
-
retryEnabled:
|
|
1290
|
-
maxRetries:
|
|
1291
|
-
retryInitialDelayMs:
|
|
1308
|
+
retryEnabled: cfg.retryEnabled,
|
|
1309
|
+
maxRetries: cfg.maxRetries,
|
|
1310
|
+
retryInitialDelayMs: cfg.retryInitialDelayMs
|
|
1292
1311
|
});
|
|
1293
1312
|
}
|
|
1294
1313
|
return {
|
|
1295
1314
|
http: this.http,
|
|
1296
|
-
fetchImpl:
|
|
1297
|
-
baseUrl:
|
|
1298
|
-
databaseId:
|
|
1315
|
+
fetchImpl: cfg.fetch,
|
|
1316
|
+
baseUrl: cfg.baseUrl,
|
|
1317
|
+
databaseId: cfg.databaseId,
|
|
1318
|
+
defaultModel: cfg.defaultModel ?? DEFAULT_AI_MODEL
|
|
1319
|
+
};
|
|
1320
|
+
}
|
|
1321
|
+
async ensureAiClient() {
|
|
1322
|
+
const cfg = await this.resolveConfig();
|
|
1323
|
+
if (!this.aiHttp) {
|
|
1324
|
+
this.aiHttp = new HttpClient({
|
|
1325
|
+
baseUrl: cfg.aiBaseUrl,
|
|
1326
|
+
apiKey: cfg.apiKey,
|
|
1327
|
+
apiSecret: cfg.apiSecret,
|
|
1328
|
+
fetchImpl: cfg.fetch,
|
|
1329
|
+
requestLoggingEnabled: this.requestLoggingEnabled,
|
|
1330
|
+
responseLoggingEnabled: this.responseLoggingEnabled,
|
|
1331
|
+
retryEnabled: cfg.retryEnabled,
|
|
1332
|
+
maxRetries: cfg.maxRetries,
|
|
1333
|
+
retryInitialDelayMs: cfg.retryInitialDelayMs
|
|
1334
|
+
});
|
|
1335
|
+
}
|
|
1336
|
+
return {
|
|
1337
|
+
http: this.aiHttp,
|
|
1338
|
+
fetchImpl: cfg.fetch,
|
|
1339
|
+
aiBaseUrl: cfg.aiBaseUrl,
|
|
1340
|
+
databaseId: cfg.databaseId,
|
|
1341
|
+
defaultModel: cfg.defaultModel ?? DEFAULT_AI_MODEL
|
|
1299
1342
|
};
|
|
1300
1343
|
}
|
|
1301
1344
|
registerStream(handle) {
|
|
@@ -1310,7 +1353,75 @@ var OnyxDatabaseImpl = class {
|
|
|
1310
1353
|
}
|
|
1311
1354
|
};
|
|
1312
1355
|
}
|
|
1356
|
+
createAiFacade() {
|
|
1357
|
+
const chat = ((contentOrRequest, options) => {
|
|
1358
|
+
if (typeof contentOrRequest === "string") {
|
|
1359
|
+
return this.chatWithContent(contentOrRequest, options);
|
|
1360
|
+
}
|
|
1361
|
+
return this.getAiChatClient().create(contentOrRequest, options);
|
|
1362
|
+
});
|
|
1363
|
+
return {
|
|
1364
|
+
chat,
|
|
1365
|
+
chatClient: () => this.getAiChatClient(),
|
|
1366
|
+
getModels: () => this.getModels(),
|
|
1367
|
+
getModel: (modelId) => this.getModel(modelId),
|
|
1368
|
+
requestScriptApproval: (input) => this.requestScriptApproval(input)
|
|
1369
|
+
};
|
|
1370
|
+
}
|
|
1371
|
+
getRequestLoggingEnabled() {
|
|
1372
|
+
return this.requestLoggingEnabled;
|
|
1373
|
+
}
|
|
1374
|
+
getResponseLoggingEnabled() {
|
|
1375
|
+
return this.responseLoggingEnabled;
|
|
1376
|
+
}
|
|
1313
1377
|
/** -------- IOnyxDatabase -------- */
|
|
1378
|
+
getAiChatClient() {
|
|
1379
|
+
return new AiChatClientImpl(
|
|
1380
|
+
() => this.ensureAiClient(),
|
|
1381
|
+
(handle) => this.registerStream(handle),
|
|
1382
|
+
() => this.requestLoggingEnabled,
|
|
1383
|
+
() => this.responseLoggingEnabled
|
|
1384
|
+
);
|
|
1385
|
+
}
|
|
1386
|
+
async chatWithContent(content, options) {
|
|
1387
|
+
const { defaultModel } = await this.ensureAiClient();
|
|
1388
|
+
const stream = options?.stream ?? false;
|
|
1389
|
+
const request = {
|
|
1390
|
+
model: options?.model ?? defaultModel,
|
|
1391
|
+
messages: [{ role: options?.role ?? "user", content }],
|
|
1392
|
+
stream
|
|
1393
|
+
};
|
|
1394
|
+
if (options && "temperature" in options) {
|
|
1395
|
+
request.temperature = options.temperature ?? null;
|
|
1396
|
+
}
|
|
1397
|
+
const result = await this.getAiChatClient().create(request, options);
|
|
1398
|
+
if (stream) return result;
|
|
1399
|
+
if (options?.raw) return result;
|
|
1400
|
+
const first = result.choices?.[0]?.message?.content;
|
|
1401
|
+
if (typeof first === "string" && first.trim().length > 0) {
|
|
1402
|
+
return first;
|
|
1403
|
+
}
|
|
1404
|
+
throw new Error("Chat completion response is missing message content");
|
|
1405
|
+
}
|
|
1406
|
+
chat(content, options) {
|
|
1407
|
+
if (typeof content === "string") {
|
|
1408
|
+
return this.chatWithContent(content, options);
|
|
1409
|
+
}
|
|
1410
|
+
return this.getAiChatClient();
|
|
1411
|
+
}
|
|
1412
|
+
async getModels() {
|
|
1413
|
+
const { http } = await this.ensureAiClient();
|
|
1414
|
+
return http.request("GET", "/v1/models");
|
|
1415
|
+
}
|
|
1416
|
+
async getModel(modelId) {
|
|
1417
|
+
const { http } = await this.ensureAiClient();
|
|
1418
|
+
const path = `/v1/models/${encodeURIComponent(modelId)}`;
|
|
1419
|
+
return http.request("GET", path);
|
|
1420
|
+
}
|
|
1421
|
+
async requestScriptApproval(input) {
|
|
1422
|
+
const { http } = await this.ensureAiClient();
|
|
1423
|
+
return http.request("POST", "/api/script-approvals", input);
|
|
1424
|
+
}
|
|
1314
1425
|
from(table) {
|
|
1315
1426
|
return new QueryBuilderImpl(this, String(table), this.defaultPartition);
|
|
1316
1427
|
}
|
|
@@ -1860,6 +1971,153 @@ var CascadeBuilderImpl = class {
|
|
|
1860
1971
|
return this.db.delete(table, primaryKey, opts);
|
|
1861
1972
|
}
|
|
1862
1973
|
};
|
|
1974
|
+
var AiChatClientImpl = class {
|
|
1975
|
+
constructor(resolveAiClient, registerStream, requestLoggingEnabled, responseLoggingEnabled) {
|
|
1976
|
+
this.resolveAiClient = resolveAiClient;
|
|
1977
|
+
this.registerStream = registerStream;
|
|
1978
|
+
this.requestLoggingEnabled = requestLoggingEnabled;
|
|
1979
|
+
this.responseLoggingEnabled = responseLoggingEnabled;
|
|
1980
|
+
}
|
|
1981
|
+
normalizeEventData(rawEvent) {
|
|
1982
|
+
const lines = rawEvent.split("\n");
|
|
1983
|
+
const dataLines = [];
|
|
1984
|
+
for (const line of lines) {
|
|
1985
|
+
const trimmed = line.trim();
|
|
1986
|
+
if (!trimmed || trimmed.startsWith(":")) continue;
|
|
1987
|
+
if (trimmed.startsWith("data:")) {
|
|
1988
|
+
dataLines.push(trimmed.slice(5).trim());
|
|
1989
|
+
} else {
|
|
1990
|
+
dataLines.push(trimmed);
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
if (!dataLines.length) return null;
|
|
1994
|
+
const joined = dataLines.join("\n").trim();
|
|
1995
|
+
return joined.length > 0 ? joined : null;
|
|
1996
|
+
}
|
|
1997
|
+
logRequest(url, body, headers) {
|
|
1998
|
+
if (!this.requestLoggingEnabled()) return;
|
|
1999
|
+
console.log(`POST ${url}`);
|
|
2000
|
+
if (body != null) {
|
|
2001
|
+
const serialized = typeof body === "string" ? body : JSON.stringify(body);
|
|
2002
|
+
console.log(serialized);
|
|
2003
|
+
}
|
|
2004
|
+
const headerLog = { ...headers };
|
|
2005
|
+
if (headerLog["x-onyx-secret"]) headerLog["x-onyx-secret"] = "[REDACTED]";
|
|
2006
|
+
console.log("Headers:", headerLog);
|
|
2007
|
+
}
|
|
2008
|
+
logResponse(status, statusText, raw) {
|
|
2009
|
+
if (!this.responseLoggingEnabled()) return;
|
|
2010
|
+
const statusLine = `${status} ${statusText}`.trim();
|
|
2011
|
+
console.log(statusLine);
|
|
2012
|
+
if (raw && raw.trim().length > 0) {
|
|
2013
|
+
console.log(raw);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2016
|
+
toOnyxError(status, statusText, raw) {
|
|
2017
|
+
let parsed = raw;
|
|
2018
|
+
try {
|
|
2019
|
+
parsed = parseJsonAllowNaN(raw);
|
|
2020
|
+
} catch {
|
|
2021
|
+
}
|
|
2022
|
+
const message = typeof parsed === "object" && parsed !== null && "error" in parsed && typeof parsed.error === "object" && typeof parsed.error?.message === "string" ? String(parsed.error.message) : `${status} ${statusText}`;
|
|
2023
|
+
return new OnyxHttpError(message, status, statusText, parsed, raw);
|
|
2024
|
+
}
|
|
2025
|
+
async create(request, options) {
|
|
2026
|
+
const body = { ...request, stream: !!request.stream };
|
|
2027
|
+
const { http, fetchImpl, aiBaseUrl, databaseId } = await this.resolveAiClient();
|
|
2028
|
+
const params = new URLSearchParams();
|
|
2029
|
+
const scopedDb = options?.databaseId ?? databaseId;
|
|
2030
|
+
if (scopedDb) params.append("databaseId", scopedDb);
|
|
2031
|
+
const path = `/v1/chat/completions${params.size ? `?${params.toString()}` : ""}`;
|
|
2032
|
+
if (!body.stream) {
|
|
2033
|
+
return http.request("POST", path, body);
|
|
2034
|
+
}
|
|
2035
|
+
const url = `${aiBaseUrl}${path}`;
|
|
2036
|
+
const headers = http.headers({ Accept: "text/event-stream" });
|
|
2037
|
+
this.logRequest(url, body, headers);
|
|
2038
|
+
const res = await fetchImpl(url, {
|
|
2039
|
+
method: "POST",
|
|
2040
|
+
headers,
|
|
2041
|
+
body: JSON.stringify(body)
|
|
2042
|
+
});
|
|
2043
|
+
if (!res.ok) {
|
|
2044
|
+
const raw = await res.text();
|
|
2045
|
+
this.logResponse(res.status, res.statusText, raw);
|
|
2046
|
+
throw this.toOnyxError(res.status, res.statusText, raw);
|
|
2047
|
+
}
|
|
2048
|
+
this.logResponse(res.status, res.statusText);
|
|
2049
|
+
const bodyStream = res.body;
|
|
2050
|
+
const reader = bodyStream && typeof bodyStream.getReader === "function" ? bodyStream.getReader() : null;
|
|
2051
|
+
if (!reader) {
|
|
2052
|
+
throw new OnyxHttpError(
|
|
2053
|
+
"Streaming response body is not readable",
|
|
2054
|
+
res.status,
|
|
2055
|
+
res.statusText,
|
|
2056
|
+
null,
|
|
2057
|
+
""
|
|
2058
|
+
);
|
|
2059
|
+
}
|
|
2060
|
+
let canceled = false;
|
|
2061
|
+
const handle = {
|
|
2062
|
+
cancel: () => {
|
|
2063
|
+
if (canceled) return;
|
|
2064
|
+
canceled = true;
|
|
2065
|
+
try {
|
|
2066
|
+
reader.cancel?.();
|
|
2067
|
+
} catch {
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
};
|
|
2071
|
+
const registered = this.registerStream(handle);
|
|
2072
|
+
const normalizeEvent = (rawEvent) => this.normalizeEventData(rawEvent);
|
|
2073
|
+
const stream = {
|
|
2074
|
+
async *[Symbol.asyncIterator]() {
|
|
2075
|
+
const decoder = new TextDecoder("utf-8");
|
|
2076
|
+
let buffer = "";
|
|
2077
|
+
try {
|
|
2078
|
+
while (!canceled) {
|
|
2079
|
+
const { done, value } = await reader.read();
|
|
2080
|
+
if (done) break;
|
|
2081
|
+
if (value) {
|
|
2082
|
+
buffer += decoder.decode(value, { stream: true });
|
|
2083
|
+
}
|
|
2084
|
+
let splitIndex = buffer.indexOf("\n\n");
|
|
2085
|
+
while (splitIndex !== -1) {
|
|
2086
|
+
const rawEvent = buffer.slice(0, splitIndex);
|
|
2087
|
+
buffer = buffer.slice(splitIndex + 2);
|
|
2088
|
+
const data = normalizeEvent(rawEvent);
|
|
2089
|
+
if (data === "[DONE]") return;
|
|
2090
|
+
if (data) {
|
|
2091
|
+
try {
|
|
2092
|
+
yield parseJsonAllowNaN(data);
|
|
2093
|
+
} catch {
|
|
2094
|
+
}
|
|
2095
|
+
}
|
|
2096
|
+
splitIndex = buffer.indexOf("\n\n");
|
|
2097
|
+
}
|
|
2098
|
+
}
|
|
2099
|
+
buffer += decoder.decode();
|
|
2100
|
+
const remaining = buffer.trim();
|
|
2101
|
+
if (remaining && remaining !== "[DONE]") {
|
|
2102
|
+
const data = normalizeEvent(remaining);
|
|
2103
|
+
if (data && data !== "[DONE]") {
|
|
2104
|
+
try {
|
|
2105
|
+
yield parseJsonAllowNaN(data);
|
|
2106
|
+
} catch {
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
} finally {
|
|
2111
|
+
registered.cancel();
|
|
2112
|
+
}
|
|
2113
|
+
},
|
|
2114
|
+
cancel() {
|
|
2115
|
+
registered.cancel();
|
|
2116
|
+
}
|
|
2117
|
+
};
|
|
2118
|
+
return stream;
|
|
2119
|
+
}
|
|
2120
|
+
};
|
|
1863
2121
|
function createOnyxFacade(resolveConfig2) {
|
|
1864
2122
|
let cachedCfg = null;
|
|
1865
2123
|
function resolveConfigWithCache(config) {
|