@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 CHANGED
@@ -18,6 +18,7 @@ TypeScript client SDK for **Onyx Cloud Database** — a zero-dependency, strict-
18
18
  - [Getting started](#getting-started-cloud--keys--connect)
19
19
  - [Install](#install)
20
20
  - [Initialize the client](#initialize-the-client)
21
+ - [Onyx AI (chat & models)](#onyx-ai-chat--models)
21
22
  - [Generate schema types](#optional-generate-typescript-types-from-your-schema)
22
23
  - [Query helpers](#query-helpers-at-a-glance)
23
24
  - [Full-text search](#full-text-search-lucene)
@@ -92,6 +93,8 @@ Set the following environment variables for your database:
92
93
  - `ONYX_DATABASE_BASE_URL`
93
94
  - `ONYX_DATABASE_API_KEY`
94
95
  - `ONYX_DATABASE_API_SECRET`
96
+ - `ONYX_AI_BASE_URL` (optional; defaults to `https://ai.onyx.dev`)
97
+ - `ONYX_DEFAULT_MODEL` (optional; used by `db.chat('...')`, defaults to `onyx`)
95
98
 
96
99
  ```ts
97
100
  import { onyx } from '@onyx.dev/onyx-database';
@@ -107,6 +110,8 @@ import { onyx } from '@onyx.dev/onyx-database';
107
110
 
108
111
  const db = onyx.init({
109
112
  baseUrl: 'https://api.onyx.dev',
113
+ aiBaseUrl: 'https://ai.onyx.dev', // optional: override AI base path
114
+ defaultModel: 'onyx', // optional: shorthand `db.chat()` model
110
115
  databaseId: 'YOUR_DATABASE_ID',
111
116
  apiKey: 'YOUR_KEY',
112
117
  apiSecret: 'YOUR_SECRET',
@@ -179,6 +184,115 @@ necessary unless you create many short‑lived clients.
179
184
 
180
185
  ---
181
186
 
187
+ ## Onyx AI (chat & models)
188
+
189
+ AI endpoints are OpenAI-compatible and use the same credentials as database calls. Use `db.ai` for chat, models, and script approvals; `db.chat()`/`db.chat('...')` remain supported as equivalent entrypoints. A shorthand `db.chat('content')` call is available and uses `config.defaultModel` (defaults to `onyx`). The AI base URL defaults to `https://ai.onyx.dev` and can be overridden with `aiBaseUrl` (or `ONYX_AI_BASE_URL`). The `databaseId` query param is optional; when omitted, the configured databaseId is used for grounding and billing.
190
+
191
+ ### Chat completions
192
+
193
+ Examples: `examples/ai/chat.ts`, `examples/ai/chat-stream.ts`.
194
+
195
+ ```ts
196
+ import { onyx } from '@onyx.dev/onyx-database';
197
+
198
+ const db = onyx.init();
199
+
200
+ const quick = await db.chat('Reply with exactly one short greeting sentence.'); // returns first message content
201
+
202
+ const completion = await db.ai.chat({
203
+ model: 'onyx-chat',
204
+ messages: [{ role: 'user', content: 'Summarize last week’s traffic.' }],
205
+ });
206
+ console.log(completion.choices[0]?.message?.content);
207
+
208
+ // Override defaults (model/role/temperature/stream) in shorthand form
209
+ const custom = await db.chat('List three colors.', {
210
+ model: 'onyx-chat',
211
+ role: 'user',
212
+ temperature: 0.2,
213
+ stream: false, // set raw: true to receive full completion response instead of the first message content
214
+ });
215
+ ```
216
+
217
+ Streaming works as an async iterable:
218
+
219
+ ```ts
220
+ const stream = await db.ai.chat({
221
+ model: 'onyx-chat',
222
+ stream: true,
223
+ messages: [{ role: 'user', content: 'Write a short onboarding checklist.' }],
224
+ });
225
+
226
+ for await (const chunk of stream) {
227
+ process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
228
+ }
229
+ // stream.cancel() is available if you need to stop early
230
+ ```
231
+
232
+ Tool calls mirror the ChatGPT TypeScript client:
233
+
234
+ ```ts
235
+ const prompt = {
236
+ model: 'onyx-chat',
237
+ messages: [{ role: 'user', content: 'Find revenue for ACME in 2023.' }],
238
+ tools: [
239
+ {
240
+ type: 'function',
241
+ function: {
242
+ name: 'get_revenue',
243
+ description: 'Fetch revenue for a company and year',
244
+ parameters: {
245
+ type: 'object',
246
+ properties: {
247
+ company: { type: 'string' },
248
+ year: { type: 'number' },
249
+ },
250
+ required: ['company', 'year'],
251
+ },
252
+ },
253
+ },
254
+ ],
255
+ };
256
+
257
+ const first = await db.ai.chat(prompt);
258
+ const toolCall = first.choices[0]?.message?.tool_calls?.[0];
259
+
260
+ if (toolCall) {
261
+ const toolResult = await getRevenue(JSON.parse(toolCall.function.arguments)); // your impl
262
+ const followup = await db.ai.chat({
263
+ model: prompt.model,
264
+ messages: [
265
+ ...prompt.messages,
266
+ first.choices[0].message,
267
+ { role: 'tool', tool_call_id: toolCall.id ?? '', content: JSON.stringify(toolResult) },
268
+ ],
269
+ });
270
+ console.log(followup.choices[0]?.message?.content);
271
+ }
272
+ ```
273
+
274
+ ### Model metadata
275
+
276
+ Example: `examples/ai/models.ts`.
277
+
278
+ ```ts
279
+ const models = await db.ai.getModels();
280
+ const chatModel = await db.ai.getModel('onyx-chat');
281
+ ```
282
+
283
+ ### Script mutation approvals
284
+
285
+ ```ts
286
+ const approval = await db.ai.requestScriptApproval({
287
+ script: "db.save({ id: 'u1', email: 'a@b.com' })",
288
+ });
289
+ if (approval.requiresApproval) {
290
+ console.log(`Requires approval until ${approval.expiresAtIso}`);
291
+ }
292
+ ```
293
+
294
+ ---
295
+
182
296
  ## Optional: generate TypeScript types from your schema
183
297
 
184
298
  The package ships a small codegen CLI that emits per-table interfaces, a `tables` enum, and a `Schema` mapping for compile-time safety and IntelliSense. Each generated interface also includes an index signature so extra properties (for graph attachments in cascade saves) don't trigger type errors.
@@ -483,6 +597,12 @@ const activeMatch = await db
483
597
  .firstOrNull();
484
598
  ```
485
599
 
600
+ **Examples**
601
+ - Table search (minScore null): `examples/query/lucine-table-search.ts`
602
+ - Table search (minScore 4.4): `examples/query/lucine-table-search-min-score.ts`
603
+ - ALL tables search (minScore null): `examples/query/lucine-search-all-tables.ts`
604
+ - ALL tables search (minScore 4.4): `examples/query/lucine-search-all-tables-min-score.ts`
605
+
486
606
  ---
487
607
 
488
608
  ## Usage examples with `User`, `Role`, `Permission`
@@ -814,10 +814,18 @@ interface RetryOptions {
814
814
  }
815
815
  interface OnyxConfig {
816
816
  baseUrl?: string;
817
+ /**
818
+ * Base URL for AI endpoints. Defaults to https://ai.onyx.dev.
819
+ */
820
+ aiBaseUrl?: string;
817
821
  databaseId?: string;
818
822
  apiKey?: string;
819
823
  apiSecret?: string;
820
824
  fetch?: FetchImpl;
825
+ /**
826
+ * Default AI model when using shorthand chat calls (`db.chat('...')`). Defaults to `onyx`.
827
+ */
828
+ defaultModel?: string;
821
829
  /**
822
830
  * Default partition for queries, `findById`, and deletes when removing by
823
831
  * primary key. Saves rely on the entity's partition field instead.
@@ -840,7 +848,306 @@ interface OnyxConfig {
840
848
  */
841
849
  retry?: RetryOptions;
842
850
  }
851
+ interface AiRequestOptions {
852
+ /**
853
+ * Optional database scope for AI calls. Defaults to the configured databaseId.
854
+ */
855
+ databaseId?: string;
856
+ }
857
+ type AiChatRole = 'system' | 'user' | 'assistant' | 'tool';
858
+ interface AiToolCallFunction {
859
+ name: string;
860
+ arguments: string;
861
+ }
862
+ interface AiToolCall {
863
+ id?: string | null;
864
+ type?: string | null;
865
+ function: AiToolCallFunction;
866
+ }
867
+ interface AiChatMessage {
868
+ role: AiChatRole;
869
+ content?: string | null;
870
+ tool_calls?: AiToolCall[] | null;
871
+ tool_call_id?: string | null;
872
+ name?: string | null;
873
+ }
874
+ interface AiToolFunction {
875
+ name: string;
876
+ description?: string | null;
877
+ parameters?: Record<string, unknown> | null;
878
+ }
879
+ interface AiTool {
880
+ type: string;
881
+ function: AiToolFunction;
882
+ }
883
+ type AiToolChoice = 'none' | 'auto' | {
884
+ type: 'function';
885
+ function: {
886
+ name: string;
887
+ };
888
+ } | null;
889
+ interface AiChatCompletionRequest {
890
+ model: string;
891
+ messages: AiChatMessage[];
892
+ stream?: boolean;
893
+ temperature?: number | null;
894
+ top_p?: number | null;
895
+ max_tokens?: number | null;
896
+ metadata?: Record<string, unknown>;
897
+ tools?: AiTool[];
898
+ tool_choice?: AiToolChoice;
899
+ user?: string | null;
900
+ }
901
+ interface AiChatCompletionUsage {
902
+ prompt_tokens?: number | null;
903
+ completion_tokens?: number | null;
904
+ total_tokens?: number | null;
905
+ }
906
+ interface AiChatCompletionChoice {
907
+ index: number;
908
+ message: AiChatMessage;
909
+ finish_reason?: string | null;
910
+ }
911
+ interface AiChatCompletionResponse {
912
+ id: string;
913
+ object: string;
914
+ created: number;
915
+ model: string;
916
+ choices: AiChatCompletionChoice[];
917
+ usage?: AiChatCompletionUsage;
918
+ }
919
+ interface AiChatCompletionChunkDelta {
920
+ role?: AiChatRole | null;
921
+ content?: string | null;
922
+ tool_calls?: AiToolCall[] | null;
923
+ tool_call_id?: string | null;
924
+ name?: string | null;
925
+ }
926
+ interface AiChatCompletionChunkChoice {
927
+ index: number;
928
+ delta: AiChatCompletionChunkDelta;
929
+ finish_reason?: string | null;
930
+ }
931
+ interface AiChatCompletionChunk {
932
+ id: string;
933
+ object: string;
934
+ created: number;
935
+ model?: string | null;
936
+ choices: AiChatCompletionChunkChoice[];
937
+ }
938
+ interface AiChatCompletionStream extends AsyncIterable<AiChatCompletionChunk> {
939
+ cancel(): void;
940
+ }
941
+ interface AiChatOptions extends AiRequestOptions {
942
+ /**
943
+ * Model to use for the shorthand `db.chat()` call. Defaults to config.defaultModel or `onyx`.
944
+ */
945
+ model?: string;
946
+ /**
947
+ * Role for the constructed message. Defaults to `user`.
948
+ */
949
+ role?: AiChatRole;
950
+ /**
951
+ * Temperature for the completion. Omit to use the service default.
952
+ */
953
+ temperature?: number | null;
954
+ /**
955
+ * Enable SSE streaming. Defaults to `false`.
956
+ */
957
+ stream?: boolean;
958
+ /**
959
+ * When true, return the raw completion response instead of the first message content.
960
+ */
961
+ raw?: boolean;
962
+ }
963
+ interface AiChatClient {
964
+ create(request: AiChatCompletionRequest & {
965
+ stream?: false;
966
+ }, options?: AiRequestOptions): Promise<AiChatCompletionResponse>;
967
+ create(request: AiChatCompletionRequest & {
968
+ stream: true;
969
+ }, options?: AiRequestOptions): Promise<AiChatCompletionStream>;
970
+ create(request: AiChatCompletionRequest, options?: AiRequestOptions): Promise<AiChatCompletionResponse | AiChatCompletionStream>;
971
+ }
972
+ interface AiScriptApprovalRequest {
973
+ script: string;
974
+ }
975
+ interface AiScriptApprovalResponse {
976
+ normalizedScript: string;
977
+ expiresAtIso: string;
978
+ requiresApproval: boolean;
979
+ findings?: string;
980
+ }
981
+ interface AiModelsResponse {
982
+ object: string;
983
+ data: AiModel[];
984
+ }
985
+ interface AiModel {
986
+ id: string;
987
+ object: string;
988
+ created: number;
989
+ owned_by: string;
990
+ }
991
+ interface AiErrorResponse {
992
+ error?: string | {
993
+ message?: string;
994
+ [key: string]: unknown;
995
+ } | null;
996
+ }
997
+ interface AiClient {
998
+ /**
999
+ * Run a chat completion. Accepts shorthand strings or full requests.
1000
+ *
1001
+ * @example
1002
+ * ```ts
1003
+ * const quick = await db.ai.chat('Summarize last week.'); // returns first message content
1004
+ * const completion = await db.ai.chat(
1005
+ * { model: 'onyx-chat', messages: [{ role: 'user', content: 'Summarize last week.' }] },
1006
+ * { databaseId: 'db1', raw: true }, // returns full response
1007
+ * );
1008
+ * ```
1009
+ */
1010
+ chat(content: string, options?: AiChatOptions & {
1011
+ stream?: false;
1012
+ raw?: false | undefined;
1013
+ }): Promise<string>;
1014
+ chat(content: string, options: AiChatOptions & {
1015
+ stream: true;
1016
+ }): Promise<AiChatCompletionStream>;
1017
+ chat(content: string, options: AiChatOptions & {
1018
+ raw: true;
1019
+ }): Promise<AiChatCompletionResponse | AiChatCompletionStream>;
1020
+ chat(request: AiChatCompletionRequest & {
1021
+ stream?: false;
1022
+ }, options?: AiRequestOptions): Promise<AiChatCompletionResponse>;
1023
+ chat(request: AiChatCompletionRequest & {
1024
+ stream: true;
1025
+ }, options?: AiRequestOptions): Promise<AiChatCompletionStream>;
1026
+ chat(request: AiChatCompletionRequest, options?: AiRequestOptions): Promise<AiChatCompletionResponse | AiChatCompletionStream>;
1027
+ /**
1028
+ * Access the chat client for more control over streaming and cancellation.
1029
+ */
1030
+ chatClient(): AiChatClient;
1031
+ /**
1032
+ * List available AI models.
1033
+ *
1034
+ * @example
1035
+ * ```ts
1036
+ * const models = await db.ai.getModels();
1037
+ * ```
1038
+ */
1039
+ getModels(): Promise<AiModelsResponse>;
1040
+ /**
1041
+ * Retrieve a single AI model by ID.
1042
+ *
1043
+ * @example
1044
+ * ```ts
1045
+ * const model = await db.ai.getModel('onyx-chat');
1046
+ * ```
1047
+ */
1048
+ getModel(modelId: string): Promise<AiModel>;
1049
+ /**
1050
+ * Request mutation approval for a script.
1051
+ *
1052
+ * @example
1053
+ * ```ts
1054
+ * const approval = await db.ai.requestScriptApproval({
1055
+ * script: "db.save({ id: 'u1', email: 'a@b.com' })"
1056
+ * });
1057
+ * ```
1058
+ */
1059
+ requestScriptApproval(input: AiScriptApprovalRequest): Promise<AiScriptApprovalResponse>;
1060
+ }
843
1061
  interface IOnyxDatabase<Schema = Record<string, unknown>> {
1062
+ /**
1063
+ * AI helpers (chat, models, script approvals) grouped under `db.ai`.
1064
+ *
1065
+ * @example
1066
+ * ```ts
1067
+ * const completion = await db.ai.chat({
1068
+ * model: 'onyx-chat',
1069
+ * messages: [{ role: 'user', content: 'Summarize last week.' }],
1070
+ * });
1071
+ * ```
1072
+ */
1073
+ ai: AiClient;
1074
+ /**
1075
+ * Access OpenAI-compatible chat completions via `db.chat('...')` or `db.chat().create(...)`.
1076
+ *
1077
+ * @example
1078
+ * ```ts
1079
+ * const completion = await db.chat('Summarize last week.'); // returns first message content
1080
+ * ```
1081
+ *
1082
+ * @example
1083
+ * ```ts
1084
+ * const chat = db.chat();
1085
+ * const completion = await chat.create({
1086
+ * model: 'onyx-chat',
1087
+ * messages: [{ role: 'user', content: 'Summarize last week.' }],
1088
+ * });
1089
+ * ```
1090
+ *
1091
+ * @example
1092
+ * ```ts
1093
+ * const stream = await db
1094
+ * .chat()
1095
+ * .create({
1096
+ * model: 'onyx-chat',
1097
+ * stream: true,
1098
+ * messages: [{ role: 'user', content: 'Draft an onboarding checklist.' }],
1099
+ * });
1100
+ * for await (const chunk of stream) {
1101
+ * process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
1102
+ * }
1103
+ * ```
1104
+ */
1105
+ chat(content: string, options?: AiChatOptions & {
1106
+ stream?: false;
1107
+ raw?: false | undefined;
1108
+ }): Promise<string>;
1109
+ chat(content: string, options: AiChatOptions & {
1110
+ stream: true;
1111
+ }): Promise<AiChatCompletionStream>;
1112
+ chat(content: string, options: AiChatOptions & {
1113
+ raw: true;
1114
+ }): Promise<AiChatCompletionResponse | AiChatCompletionStream>;
1115
+ chat(): AiChatClient;
1116
+ /**
1117
+ * List available AI models.
1118
+ *
1119
+ * @deprecated Prefer `db.ai.getModels()`.
1120
+ *
1121
+ * @example
1122
+ * ```ts
1123
+ * const models = await db.getModels();
1124
+ * ```
1125
+ */
1126
+ getModels(): Promise<AiModelsResponse>;
1127
+ /**
1128
+ * Retrieve a single AI model by ID.
1129
+ *
1130
+ * @deprecated Prefer `db.ai.getModel(...)`.
1131
+ *
1132
+ * @example
1133
+ * ```ts
1134
+ * const model = await db.getModel('onyx-chat');
1135
+ * ```
1136
+ */
1137
+ getModel(modelId: string): Promise<AiModel>;
1138
+ /**
1139
+ * Request mutation approval for a script.
1140
+ *
1141
+ * @deprecated Prefer `db.ai.requestScriptApproval(...)`.
1142
+ *
1143
+ * @example
1144
+ * ```ts
1145
+ * const approval = await db.requestScriptApproval({
1146
+ * script: "db.save({ id: 'u1', email: 'a@b.com' })"
1147
+ * });
1148
+ * ```
1149
+ */
1150
+ requestScriptApproval(input: AiScriptApprovalRequest): Promise<AiScriptApprovalResponse>;
844
1151
  /**
845
1152
  * Begin a query against a table.
846
1153
  *
@@ -1450,4 +1757,4 @@ declare const substring: (attribute: string, from: number, length: number) => st
1450
1757
  declare const replace: (attribute: string, pattern: string, repl: string) => string;
1451
1758
  declare const percentile: (attribute: string, p: number) => string;
1452
1759
 
1453
- export { inOp as $, type QueryCriteriaOperator as A, type Sort as B, type StreamAction as C, type OnyxDocument as D, type FetchResponse as E, type FullTextQuery as F, type FetchImpl as G, type QueryCriteria as H, type IOnyxDatabase as I, type QueryCondition as J, type SelectQuery as K, type LogicalOperator as L, type QueryPage as M, type IConditionBuilder as N, type OnyxFacade as O, type IQueryBuilder as P, QueryResults as Q, type RetryOptions as R, type SecretMetadata as S, type ISaveBuilder as T, type UpdateQuery as U, type ICascadeBuilder as V, type ICascadeRelationshipBuilder as W, asc as X, desc as Y, eq as Z, neq as _, type QueryResultsPromise as a, within as a0, notIn as a1, notWithin as a2, between as a3, gt as a4, gte as a5, lt as a6, lte as a7, matches as a8, search as a9, notMatches as aa, like as ab, notLike as ac, contains as ad, containsIgnoreCase as ae, notContains as af, notContainsIgnoreCase as ag, startsWith as ah, notStartsWith as ai, isNull as aj, notNull as ak, avg as al, sum as am, count as an, min as ao, max as ap, std as aq, variance as ar, median as as, upper as at, lower as au, substring as av, replace as aw, percentile as ax, 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 };
1760
+ export { type SchemaTriggerChange as $, type AiRequestOptions as A, type SecretsListResponse as B, type SecretSaveRequest as C, type SchemaDataType as D, type SchemaIdentifierGenerator as E, type FullTextQuery as F, type SchemaIdentifier as G, type SchemaAttribute as H, type IOnyxDatabase as I, type SchemaIndexType as J, type SchemaIndex as K, type SchemaResolver as L, type SchemaTriggerEvent as M, type SchemaTrigger as N, type OnyxFacade as O, type SchemaEntity as P, QueryResults as Q, type RetryOptions as R, type SecretMetadata as S, type SchemaRevisionMetadata as T, type SchemaRevision as U, type SchemaHistoryEntry as V, type SchemaUpsertRequest as W, type SchemaValidationResult as X, type SchemaAttributeChange as Y, type SchemaIndexChange as Z, type SchemaResolverChange as _, type QueryResultsPromise as a, type SchemaTableDiff as a0, type SchemaDiff as a1, type QueryCriteriaOperator as a2, type LogicalOperator as a3, type Sort as a4, type StreamAction as a5, type OnyxDocument as a6, type FetchResponse as a7, type FetchImpl as a8, type QueryCriteria 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 QueryCondition as aa, type SelectQuery as ab, type UpdateQuery as ac, type QueryPage as ad, type IConditionBuilder as ae, type IQueryBuilder as af, type ISaveBuilder as ag, type ICascadeBuilder as ah, type ICascadeRelationshipBuilder as ai, asc as aj, desc as ak, eq as al, neq as am, inOp as an, within as ao, notIn as ap, notWithin as aq, between as ar, gt as as, gte as at, lt as au, lte as av, matches as aw, search as ax, notMatches as ay, like 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 AiChatOptions as r, type AiChatClient as s, type AiScriptApprovalRequest as t, type AiScriptApprovalResponse as u, type AiModelsResponse as v, type AiModel as w, type AiErrorResponse as x, type AiClient as y, type SecretRecord as z };