@onyx.dev/onyx-database 1.0.3 → 1.2.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.
@@ -7,6 +7,11 @@
7
7
  * ```
8
8
  */
9
9
  type QueryCriteriaOperator = 'EQUAL' | 'NOT_EQUAL' | 'IN' | 'NOT_IN' | 'GREATER_THAN' | 'GREATER_THAN_EQUAL' | 'LESS_THAN' | 'LESS_THAN_EQUAL' | 'MATCHES' | 'NOT_MATCHES' | 'BETWEEN' | 'LIKE' | 'NOT_LIKE' | 'CONTAINS' | 'CONTAINS_IGNORE_CASE' | 'NOT_CONTAINS' | 'NOT_CONTAINS_IGNORE_CASE' | 'STARTS_WITH' | 'NOT_STARTS_WITH' | 'IS_NULL' | 'NOT_NULL';
10
+ /** Value payload for full-text (Lucene) searches. */
11
+ interface FullTextQuery {
12
+ queryText: string;
13
+ minScore: number | null;
14
+ }
10
15
  /** Logical operator used to join conditions in a query. */
11
16
  type LogicalOperator = 'AND' | 'OR';
12
17
  /**
@@ -133,6 +138,7 @@ type QueryCondition = {
133
138
  */
134
139
  interface SelectQuery {
135
140
  type: 'SelectQuery';
141
+ table?: string | null;
136
142
  fields?: string[] | null;
137
143
  conditions?: QueryCondition | null;
138
144
  sort?: Sort[] | null;
@@ -473,6 +479,16 @@ interface IQueryBuilder<T = unknown> {
473
479
  * ```
474
480
  */
475
481
  resolve(...values: Array<string | string[]>): IQueryBuilder<T>;
482
+ /**
483
+ * Adds a Lucene full-text search predicate.
484
+ * @example
485
+ * ```ts
486
+ * const results = await db.from('User').search('hello world', 4.4).list();
487
+ * ```
488
+ * @param queryText - Text to match against `__full_text__`.
489
+ * @param minScore - Optional minimum score; serializes as `null` when omitted.
490
+ */
491
+ search(queryText: string, minScore?: number | null): IQueryBuilder<T>;
476
492
  /**
477
493
  * Adds a filter condition.
478
494
  * @example
@@ -798,6 +814,10 @@ interface RetryOptions {
798
814
  }
799
815
  interface OnyxConfig {
800
816
  baseUrl?: string;
817
+ /**
818
+ * Base URL for AI endpoints. Defaults to https://ai.onyx.dev.
819
+ */
820
+ aiBaseUrl?: string;
801
821
  databaseId?: string;
802
822
  apiKey?: string;
803
823
  apiSecret?: string;
@@ -824,7 +844,187 @@ interface OnyxConfig {
824
844
  */
825
845
  retry?: RetryOptions;
826
846
  }
847
+ interface AiRequestOptions {
848
+ /**
849
+ * Optional database scope for AI calls. Defaults to the configured databaseId.
850
+ */
851
+ databaseId?: string;
852
+ }
853
+ type AiChatRole = 'system' | 'user' | 'assistant' | 'tool';
854
+ interface AiToolCallFunction {
855
+ name: string;
856
+ arguments: string;
857
+ }
858
+ interface AiToolCall {
859
+ id?: string | null;
860
+ type?: string | null;
861
+ function: AiToolCallFunction;
862
+ }
863
+ interface AiChatMessage {
864
+ role: AiChatRole;
865
+ content?: string | null;
866
+ tool_calls?: AiToolCall[] | null;
867
+ tool_call_id?: string | null;
868
+ name?: string | null;
869
+ }
870
+ interface AiToolFunction {
871
+ name: string;
872
+ description?: string | null;
873
+ parameters?: Record<string, unknown> | null;
874
+ }
875
+ interface AiTool {
876
+ type: string;
877
+ function: AiToolFunction;
878
+ }
879
+ type AiToolChoice = 'none' | 'auto' | {
880
+ type: 'function';
881
+ function: {
882
+ name: string;
883
+ };
884
+ } | null;
885
+ interface AiChatCompletionRequest {
886
+ model: string;
887
+ messages: AiChatMessage[];
888
+ stream?: boolean;
889
+ temperature?: number | null;
890
+ top_p?: number | null;
891
+ max_tokens?: number | null;
892
+ metadata?: Record<string, unknown>;
893
+ tools?: AiTool[];
894
+ tool_choice?: AiToolChoice;
895
+ user?: string | null;
896
+ }
897
+ interface AiChatCompletionUsage {
898
+ prompt_tokens?: number | null;
899
+ completion_tokens?: number | null;
900
+ total_tokens?: number | null;
901
+ }
902
+ interface AiChatCompletionChoice {
903
+ index: number;
904
+ message: AiChatMessage;
905
+ finish_reason?: string | null;
906
+ }
907
+ interface AiChatCompletionResponse {
908
+ id: string;
909
+ object: string;
910
+ created: number;
911
+ model: string;
912
+ choices: AiChatCompletionChoice[];
913
+ usage?: AiChatCompletionUsage;
914
+ }
915
+ interface AiChatCompletionChunkDelta {
916
+ role?: AiChatRole | null;
917
+ content?: string | null;
918
+ tool_calls?: AiToolCall[] | null;
919
+ tool_call_id?: string | null;
920
+ name?: string | null;
921
+ }
922
+ interface AiChatCompletionChunkChoice {
923
+ index: number;
924
+ delta: AiChatCompletionChunkDelta;
925
+ finish_reason?: string | null;
926
+ }
927
+ interface AiChatCompletionChunk {
928
+ id: string;
929
+ object: string;
930
+ created: number;
931
+ model?: string | null;
932
+ choices: AiChatCompletionChunkChoice[];
933
+ }
934
+ interface AiChatCompletionStream extends AsyncIterable<AiChatCompletionChunk> {
935
+ cancel(): void;
936
+ }
937
+ interface AiChatClient {
938
+ create(request: AiChatCompletionRequest & {
939
+ stream?: false;
940
+ }, options?: AiRequestOptions): Promise<AiChatCompletionResponse>;
941
+ create(request: AiChatCompletionRequest & {
942
+ stream: true;
943
+ }, options?: AiRequestOptions): Promise<AiChatCompletionStream>;
944
+ create(request: AiChatCompletionRequest, options?: AiRequestOptions): Promise<AiChatCompletionResponse | AiChatCompletionStream>;
945
+ }
946
+ interface AiScriptApprovalRequest {
947
+ script: string;
948
+ }
949
+ interface AiScriptApprovalResponse {
950
+ normalizedScript: string;
951
+ expiresAtIso: string;
952
+ requiresApproval: boolean;
953
+ findings?: string;
954
+ }
955
+ interface AiModelsResponse {
956
+ object: string;
957
+ data: AiModel[];
958
+ }
959
+ interface AiModel {
960
+ id: string;
961
+ object: string;
962
+ created: number;
963
+ owned_by: string;
964
+ }
965
+ interface AiErrorResponse {
966
+ error?: string | {
967
+ message?: string;
968
+ [key: string]: unknown;
969
+ } | null;
970
+ }
827
971
  interface IOnyxDatabase<Schema = Record<string, unknown>> {
972
+ /**
973
+ * Access OpenAI-compatible chat completions.
974
+ *
975
+ * @example
976
+ * ```ts
977
+ * const chat = db.chat();
978
+ * const completion = await chat.create({
979
+ * model: 'onyx-chat',
980
+ * messages: [{ role: 'user', content: 'Summarize last week.' }],
981
+ * });
982
+ * ```
983
+ *
984
+ * @example
985
+ * ```ts
986
+ * const stream = await db
987
+ * .chat()
988
+ * .create({
989
+ * model: 'onyx-chat',
990
+ * stream: true,
991
+ * messages: [{ role: 'user', content: 'Draft an onboarding checklist.' }],
992
+ * });
993
+ * for await (const chunk of stream) {
994
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
995
+ * }
996
+ * ```
997
+ */
998
+ chat(): AiChatClient;
999
+ /**
1000
+ * List available AI models.
1001
+ *
1002
+ * @example
1003
+ * ```ts
1004
+ * const models = await db.getModels();
1005
+ * ```
1006
+ */
1007
+ getModels(): Promise<AiModelsResponse>;
1008
+ /**
1009
+ * Retrieve a single AI model by ID.
1010
+ *
1011
+ * @example
1012
+ * ```ts
1013
+ * const model = await db.getModel('onyx-chat');
1014
+ * ```
1015
+ */
1016
+ getModel(modelId: string): Promise<AiModel>;
1017
+ /**
1018
+ * Request mutation approval for a script.
1019
+ *
1020
+ * @example
1021
+ * ```ts
1022
+ * const approval = await db.requestScriptApproval({
1023
+ * script: "db.save({ id: 'u1', email: 'a@b.com' })"
1024
+ * });
1025
+ * ```
1026
+ */
1027
+ requestScriptApproval(input: AiScriptApprovalRequest): Promise<AiScriptApprovalResponse>;
828
1028
  /**
829
1029
  * Begin a query against a table.
830
1030
  *
@@ -861,6 +1061,18 @@ interface IOnyxDatabase<Schema = Record<string, unknown>> {
861
1061
  * @param fields Field names to project; omit to select all.
862
1062
  */
863
1063
  select(...fields: string[]): IQueryBuilder<Record<string, unknown>>;
1064
+ /**
1065
+ * Run a Lucene full-text search across all tables.
1066
+ *
1067
+ * @example
1068
+ * ```ts
1069
+ * const results = await db.search('hello world', 4.4).list();
1070
+ * ```
1071
+ *
1072
+ * @param queryText Text to match against `__full_text__`.
1073
+ * @param minScore Optional minimum score; serialized as `null` when omitted.
1074
+ */
1075
+ search(queryText: string, minScore?: number | null): IQueryBuilder<Record<string, unknown>>;
864
1076
  /**
865
1077
  * Include related records in the next save or delete.
866
1078
  *
@@ -1395,6 +1607,7 @@ declare const gte: (field: string, value: unknown) => ConditionBuilderImpl;
1395
1607
  declare const lt: (field: string, value: unknown) => ConditionBuilderImpl;
1396
1608
  declare const lte: (field: string, value: unknown) => ConditionBuilderImpl;
1397
1609
  declare const matches: (field: string, regex: string) => ConditionBuilderImpl;
1610
+ declare const search: (queryText: string, minScore?: number | null) => ConditionBuilderImpl;
1398
1611
  declare const notMatches: (field: string, regex: string) => ConditionBuilderImpl;
1399
1612
  declare const like: (field: string, pattern: string) => ConditionBuilderImpl;
1400
1613
  declare const notLike: (field: string, pattern: string) => ConditionBuilderImpl;
@@ -1421,4 +1634,4 @@ declare const substring: (attribute: string, from: number, length: number) => st
1421
1634
  declare const replace: (attribute: string, pattern: string, repl: string) => string;
1422
1635
  declare const percentile: (attribute: string, p: number) => string;
1423
1636
 
1424
- export { within as $, type QueryCriteriaOperator as A, type Sort as B, type StreamAction as C, type OnyxDocument as D, type FetchImpl as E, type FetchResponse as F, type QueryCriteria as G, type QueryCondition as H, type IOnyxDatabase as I, type SelectQuery as J, type QueryPage as K, type LogicalOperator as L, type IConditionBuilder as M, type IQueryBuilder as N, type OnyxFacade as O, type ISaveBuilder as P, QueryResults as Q, type RetryOptions as R, type SecretMetadata as S, type ICascadeBuilder as T, type UpdateQuery as U, type ICascadeRelationshipBuilder as V, asc as W, desc as X, eq as Y, neq as Z, inOp as _, type QueryResultsPromise as a, notIn as a0, notWithin as a1, between as a2, gt as a3, gte as a4, lt as a5, lte as a6, matches as a7, notMatches as a8, like as a9, notLike as aa, contains as ab, containsIgnoreCase as ac, notContains as ad, notContainsIgnoreCase as ae, startsWith as af, notStartsWith as ag, isNull as ah, notNull as ai, avg as aj, sum as ak, count as al, min as am, max as an, std as ao, variance as ap, median as aq, upper as ar, lower as as, substring as at, replace as au, percentile as av, type OnyxConfig as b, type SecretRecord as c, type SecretsListResponse as d, type SecretSaveRequest as e, type SchemaDataType as f, type SchemaIdentifierGenerator as g, type SchemaIdentifier as h, type SchemaAttribute as i, type SchemaIndexType as j, type SchemaIndex as k, type SchemaResolver as l, type SchemaTriggerEvent as m, type SchemaTrigger as n, type SchemaEntity as o, type SchemaRevisionMetadata as p, type SchemaRevision as q, type SchemaHistoryEntry as r, type SchemaUpsertRequest as s, type SchemaValidationResult as t, type SchemaAttributeChange as u, type SchemaIndexChange as v, type SchemaResolverChange as w, type SchemaTriggerChange as x, type SchemaTableDiff as y, type SchemaDiff as z };
1637
+ export { type SchemaDiff as $, type AiRequestOptions as A, type SchemaDataType as B, type SchemaIdentifierGenerator as C, type SchemaIdentifier as D, type SchemaAttribute as E, type FullTextQuery as F, type SchemaIndexType as G, type SchemaIndex as H, type IOnyxDatabase as I, type SchemaResolver as J, type SchemaTriggerEvent as K, type SchemaTrigger as L, type SchemaEntity as M, type SchemaRevisionMetadata as N, type OnyxFacade as O, type SchemaRevision as P, QueryResults as Q, type RetryOptions as R, type SecretMetadata as S, type SchemaHistoryEntry as T, type SchemaUpsertRequest as U, type SchemaValidationResult as V, type SchemaAttributeChange as W, type SchemaIndexChange as X, type SchemaResolverChange as Y, type SchemaTriggerChange as Z, type SchemaTableDiff as _, type QueryResultsPromise as a, type QueryCriteriaOperator as a0, type LogicalOperator as a1, type Sort as a2, type StreamAction as a3, type OnyxDocument as a4, type FetchResponse as a5, type FetchImpl as a6, type QueryCriteria as a7, type QueryCondition as a8, type SelectQuery as a9, containsIgnoreCase as aA, notContains as aB, notContainsIgnoreCase as aC, startsWith as aD, notStartsWith as aE, isNull as aF, notNull as aG, avg as aH, sum as aI, count as aJ, min as aK, max as aL, std as aM, variance as aN, median as aO, upper as aP, lower as aQ, substring as aR, replace as aS, percentile as aT, type UpdateQuery as aa, type QueryPage as ab, type IConditionBuilder as ac, type IQueryBuilder as ad, type ISaveBuilder as ae, type ICascadeBuilder as af, type ICascadeRelationshipBuilder as ag, asc as ah, desc as ai, eq as aj, neq as ak, inOp as al, within as am, notIn as an, notWithin as ao, between as ap, gt as aq, gte as ar, lt as as, lte as at, matches as au, search as av, notMatches as aw, like as ax, notLike as ay, contains as az, type OnyxConfig as b, type AiChatRole as c, type AiToolCallFunction as d, type AiToolCall as e, type AiChatMessage as f, type AiToolFunction as g, type AiTool as h, type AiToolChoice as i, type AiChatCompletionRequest as j, type AiChatCompletionUsage as k, type AiChatCompletionChoice as l, type AiChatCompletionResponse as m, type AiChatCompletionChunkDelta as n, type AiChatCompletionChunkChoice as o, type AiChatCompletionChunk as p, type AiChatCompletionStream as q, type AiChatClient as r, type AiScriptApprovalRequest as s, type AiScriptApprovalResponse as t, type AiModelsResponse as u, type AiModel as v, type AiErrorResponse as w, type SecretRecord as x, type SecretsListResponse as y, type SecretSaveRequest as z };
package/dist/edge.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  // src/config/defaults.ts
4
4
  var DEFAULT_BASE_URL = "https://api.onyx.dev";
5
+ var DEFAULT_AI_BASE_URL = "https://ai.onyx.dev";
5
6
  var sanitizeBaseUrl = (u) => u.replace(/\/+$/, "");
6
7
 
7
8
  // src/errors/config-error.ts
@@ -53,6 +54,7 @@ function readEnv(targetId) {
53
54
  if (targetId && envId !== targetId) return {};
54
55
  const res = dropUndefined({
55
56
  baseUrl: pick("ONYX_DATABASE_BASE_URL"),
57
+ aiBaseUrl: pick("ONYX_AI_BASE_URL"),
56
58
  databaseId: envId,
57
59
  apiKey: pick("ONYX_DATABASE_API_KEY"),
58
60
  apiSecret: pick("ONYX_DATABASE_API_SECRET")
@@ -71,11 +73,13 @@ async function resolveConfig(input) {
71
73
  const env = readEnv(input?.databaseId);
72
74
  const merged = {
73
75
  baseUrl: DEFAULT_BASE_URL,
76
+ aiBaseUrl: DEFAULT_AI_BASE_URL,
74
77
  ...dropUndefined(env),
75
78
  ...dropUndefined(input)
76
79
  };
77
80
  dbg("merged (pre-validate):", mask(merged));
78
81
  const baseUrl = sanitizeBaseUrl(merged.baseUrl ?? DEFAULT_BASE_URL);
82
+ const aiBaseUrl = sanitizeBaseUrl(merged.aiBaseUrl ?? DEFAULT_AI_BASE_URL);
79
83
  const databaseId = merged.databaseId ?? "";
80
84
  const apiKey = merged.apiKey ?? "";
81
85
  const apiSecret = merged.apiSecret ?? "";
@@ -100,6 +104,7 @@ async function resolveConfig(input) {
100
104
  }
101
105
  const resolved = {
102
106
  baseUrl,
107
+ aiBaseUrl,
103
108
  databaseId,
104
109
  apiKey,
105
110
  apiSecret,
@@ -1120,6 +1125,7 @@ var OnyxDatabaseImpl = class {
1120
1125
  cfgPromise;
1121
1126
  resolved = null;
1122
1127
  http = null;
1128
+ aiHttp = null;
1123
1129
  streams = /* @__PURE__ */ new Set();
1124
1130
  requestLoggingEnabled;
1125
1131
  responseLoggingEnabled;
@@ -1154,6 +1160,30 @@ var OnyxDatabaseImpl = class {
1154
1160
  databaseId: this.resolved.databaseId
1155
1161
  };
1156
1162
  }
1163
+ async ensureAiClient() {
1164
+ if (!this.resolved) {
1165
+ this.resolved = await this.cfgPromise;
1166
+ }
1167
+ if (!this.aiHttp) {
1168
+ this.aiHttp = new HttpClient({
1169
+ baseUrl: this.resolved.aiBaseUrl,
1170
+ apiKey: this.resolved.apiKey,
1171
+ apiSecret: this.resolved.apiSecret,
1172
+ fetchImpl: this.resolved.fetch,
1173
+ requestLoggingEnabled: this.requestLoggingEnabled,
1174
+ responseLoggingEnabled: this.responseLoggingEnabled,
1175
+ retryEnabled: this.resolved.retryEnabled,
1176
+ maxRetries: this.resolved.maxRetries,
1177
+ retryInitialDelayMs: this.resolved.retryInitialDelayMs
1178
+ });
1179
+ }
1180
+ return {
1181
+ http: this.aiHttp,
1182
+ fetchImpl: this.resolved.fetch,
1183
+ aiBaseUrl: this.resolved.aiBaseUrl,
1184
+ databaseId: this.resolved.databaseId
1185
+ };
1186
+ }
1157
1187
  registerStream(handle) {
1158
1188
  this.streams.add(handle);
1159
1189
  return {
@@ -1166,7 +1196,34 @@ var OnyxDatabaseImpl = class {
1166
1196
  }
1167
1197
  };
1168
1198
  }
1199
+ getRequestLoggingEnabled() {
1200
+ return this.requestLoggingEnabled;
1201
+ }
1202
+ getResponseLoggingEnabled() {
1203
+ return this.responseLoggingEnabled;
1204
+ }
1169
1205
  /** -------- IOnyxDatabase -------- */
1206
+ chat() {
1207
+ return new AiChatClientImpl(
1208
+ () => this.ensureAiClient(),
1209
+ (handle) => this.registerStream(handle),
1210
+ () => this.requestLoggingEnabled,
1211
+ () => this.responseLoggingEnabled
1212
+ );
1213
+ }
1214
+ async getModels() {
1215
+ const { http } = await this.ensureAiClient();
1216
+ return http.request("GET", "/v1/models");
1217
+ }
1218
+ async getModel(modelId) {
1219
+ const { http } = await this.ensureAiClient();
1220
+ const path = `/v1/models/${encodeURIComponent(modelId)}`;
1221
+ return http.request("GET", path);
1222
+ }
1223
+ async requestScriptApproval(input) {
1224
+ const { http } = await this.ensureAiClient();
1225
+ return http.request("POST", "/api/script-approvals", input);
1226
+ }
1170
1227
  from(table) {
1171
1228
  return new QueryBuilderImpl(this, String(table), this.defaultPartition);
1172
1229
  }
@@ -1179,6 +1236,14 @@ var OnyxDatabaseImpl = class {
1179
1236
  qb.select(...fields);
1180
1237
  return qb;
1181
1238
  }
1239
+ search(queryText, minScore) {
1240
+ const qb = new QueryBuilderImpl(
1241
+ this,
1242
+ "ALL",
1243
+ this.defaultPartition
1244
+ );
1245
+ return qb.search(queryText, minScore);
1246
+ }
1182
1247
  cascade(...relationships) {
1183
1248
  const cb = new CascadeBuilderImpl(this);
1184
1249
  return cb.cascade(...relationships);
@@ -1465,6 +1530,7 @@ var QueryBuilderImpl = class {
1465
1530
  toSelectQuery() {
1466
1531
  return {
1467
1532
  type: "SelectQuery",
1533
+ table: this.table,
1468
1534
  fields: this.fields,
1469
1535
  conditions: this.serializableConditions(),
1470
1536
  sort: this.sort,
@@ -1504,6 +1570,13 @@ var QueryBuilderImpl = class {
1504
1570
  this.resolvers = flat.length > 0 ? flat : null;
1505
1571
  return this;
1506
1572
  }
1573
+ search(queryText, minScore) {
1574
+ return this.and({
1575
+ field: "__full_text__",
1576
+ operator: "MATCHES",
1577
+ value: { queryText, minScore: minScore ?? null }
1578
+ });
1579
+ }
1507
1580
  where(condition) {
1508
1581
  const c2 = toCondition(condition);
1509
1582
  if (!this.conditions) {
@@ -1700,6 +1773,153 @@ var CascadeBuilderImpl = class {
1700
1773
  return this.db.delete(table, primaryKey, opts);
1701
1774
  }
1702
1775
  };
1776
+ var AiChatClientImpl = class {
1777
+ constructor(resolveAiClient, registerStream, requestLoggingEnabled, responseLoggingEnabled) {
1778
+ this.resolveAiClient = resolveAiClient;
1779
+ this.registerStream = registerStream;
1780
+ this.requestLoggingEnabled = requestLoggingEnabled;
1781
+ this.responseLoggingEnabled = responseLoggingEnabled;
1782
+ }
1783
+ normalizeEventData(rawEvent) {
1784
+ const lines = rawEvent.split("\n");
1785
+ const dataLines = [];
1786
+ for (const line of lines) {
1787
+ const trimmed = line.trim();
1788
+ if (!trimmed || trimmed.startsWith(":")) continue;
1789
+ if (trimmed.startsWith("data:")) {
1790
+ dataLines.push(trimmed.slice(5).trim());
1791
+ } else {
1792
+ dataLines.push(trimmed);
1793
+ }
1794
+ }
1795
+ if (!dataLines.length) return null;
1796
+ const joined = dataLines.join("\n").trim();
1797
+ return joined.length > 0 ? joined : null;
1798
+ }
1799
+ logRequest(url, body, headers) {
1800
+ if (!this.requestLoggingEnabled()) return;
1801
+ console.log(`POST ${url}`);
1802
+ if (body != null) {
1803
+ const serialized = typeof body === "string" ? body : JSON.stringify(body);
1804
+ console.log(serialized);
1805
+ }
1806
+ const headerLog = { ...headers };
1807
+ if (headerLog["x-onyx-secret"]) headerLog["x-onyx-secret"] = "[REDACTED]";
1808
+ console.log("Headers:", headerLog);
1809
+ }
1810
+ logResponse(status, statusText, raw) {
1811
+ if (!this.responseLoggingEnabled()) return;
1812
+ const statusLine = `${status} ${statusText}`.trim();
1813
+ console.log(statusLine);
1814
+ if (raw && raw.trim().length > 0) {
1815
+ console.log(raw);
1816
+ }
1817
+ }
1818
+ toOnyxError(status, statusText, raw) {
1819
+ let parsed = raw;
1820
+ try {
1821
+ parsed = parseJsonAllowNaN(raw);
1822
+ } catch {
1823
+ }
1824
+ 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}`;
1825
+ return new OnyxHttpError(message, status, statusText, parsed, raw);
1826
+ }
1827
+ async create(request, options) {
1828
+ const body = { ...request, stream: !!request.stream };
1829
+ const { http, fetchImpl, aiBaseUrl, databaseId } = await this.resolveAiClient();
1830
+ const params = new URLSearchParams();
1831
+ const scopedDb = options?.databaseId ?? databaseId;
1832
+ if (scopedDb) params.append("databaseId", scopedDb);
1833
+ const path = `/v1/chat/completions${params.size ? `?${params.toString()}` : ""}`;
1834
+ if (!body.stream) {
1835
+ return http.request("POST", path, body);
1836
+ }
1837
+ const url = `${aiBaseUrl}${path}`;
1838
+ const headers = http.headers({ Accept: "text/event-stream" });
1839
+ this.logRequest(url, body, headers);
1840
+ const res = await fetchImpl(url, {
1841
+ method: "POST",
1842
+ headers,
1843
+ body: JSON.stringify(body)
1844
+ });
1845
+ if (!res.ok) {
1846
+ const raw = await res.text();
1847
+ this.logResponse(res.status, res.statusText, raw);
1848
+ throw this.toOnyxError(res.status, res.statusText, raw);
1849
+ }
1850
+ this.logResponse(res.status, res.statusText);
1851
+ const bodyStream = res.body;
1852
+ const reader = bodyStream && typeof bodyStream.getReader === "function" ? bodyStream.getReader() : null;
1853
+ if (!reader) {
1854
+ throw new OnyxHttpError(
1855
+ "Streaming response body is not readable",
1856
+ res.status,
1857
+ res.statusText,
1858
+ null,
1859
+ ""
1860
+ );
1861
+ }
1862
+ let canceled = false;
1863
+ const handle = {
1864
+ cancel: () => {
1865
+ if (canceled) return;
1866
+ canceled = true;
1867
+ try {
1868
+ reader.cancel?.();
1869
+ } catch {
1870
+ }
1871
+ }
1872
+ };
1873
+ const registered = this.registerStream(handle);
1874
+ const normalizeEvent = (rawEvent) => this.normalizeEventData(rawEvent);
1875
+ const stream = {
1876
+ async *[Symbol.asyncIterator]() {
1877
+ const decoder = new TextDecoder("utf-8");
1878
+ let buffer = "";
1879
+ try {
1880
+ while (!canceled) {
1881
+ const { done, value } = await reader.read();
1882
+ if (done) break;
1883
+ if (value) {
1884
+ buffer += decoder.decode(value, { stream: true });
1885
+ }
1886
+ let splitIndex = buffer.indexOf("\n\n");
1887
+ while (splitIndex !== -1) {
1888
+ const rawEvent = buffer.slice(0, splitIndex);
1889
+ buffer = buffer.slice(splitIndex + 2);
1890
+ const data = normalizeEvent(rawEvent);
1891
+ if (data === "[DONE]") return;
1892
+ if (data) {
1893
+ try {
1894
+ yield parseJsonAllowNaN(data);
1895
+ } catch {
1896
+ }
1897
+ }
1898
+ splitIndex = buffer.indexOf("\n\n");
1899
+ }
1900
+ }
1901
+ buffer += decoder.decode();
1902
+ const remaining = buffer.trim();
1903
+ if (remaining && remaining !== "[DONE]") {
1904
+ const data = normalizeEvent(remaining);
1905
+ if (data && data !== "[DONE]") {
1906
+ try {
1907
+ yield parseJsonAllowNaN(data);
1908
+ } catch {
1909
+ }
1910
+ }
1911
+ }
1912
+ } finally {
1913
+ registered.cancel();
1914
+ }
1915
+ },
1916
+ cancel() {
1917
+ registered.cancel();
1918
+ }
1919
+ };
1920
+ return stream;
1921
+ }
1922
+ };
1703
1923
  function createOnyxFacade(resolveConfig2) {
1704
1924
  let cachedCfg = null;
1705
1925
  function resolveConfigWithCache(config) {
@@ -1855,6 +2075,10 @@ var ConditionBuilderImpl = class {
1855
2075
 
1856
2076
  // src/helpers/conditions.ts
1857
2077
  var c = (field, operator, value) => new ConditionBuilderImpl({ field, operator, value });
2078
+ var fullText = (queryText, minScore) => ({
2079
+ queryText,
2080
+ minScore: minScore ?? null
2081
+ });
1858
2082
  var eq = (field, value) => c(field, "EQUAL", value);
1859
2083
  var neq = (field, value) => c(field, "NOT_EQUAL", value);
1860
2084
  function inOp(field, values) {
@@ -1877,6 +2101,7 @@ var gte = (field, value) => c(field, "GREATER_THAN_EQUAL", value);
1877
2101
  var lt = (field, value) => c(field, "LESS_THAN", value);
1878
2102
  var lte = (field, value) => c(field, "LESS_THAN_EQUAL", value);
1879
2103
  var matches = (field, regex) => c(field, "MATCHES", regex);
2104
+ var search = (queryText, minScore) => c("__full_text__", "MATCHES", fullText(queryText, minScore));
1880
2105
  var notMatches = (field, regex) => c(field, "NOT_MATCHES", regex);
1881
2106
  var like = (field, pattern) => c(field, "LIKE", pattern);
1882
2107
  var notLike = (field, pattern) => c(field, "NOT_LIKE", pattern);
@@ -1943,6 +2168,7 @@ exports.percentile = percentile;
1943
2168
  exports.replace = replace;
1944
2169
  exports.sdkName = sdkName;
1945
2170
  exports.sdkVersion = sdkVersion;
2171
+ exports.search = search;
1946
2172
  exports.startsWith = startsWith;
1947
2173
  exports.std = std;
1948
2174
  exports.substring = substring;