@dbx-tools/appkit-mastra 0.9.129 → 0.9.131

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 (51) hide show
  1. package/README.md +90 -31
  2. package/index.ts +10 -8
  3. package/lib/index.d.ts +10 -8
  4. package/lib/index.js +8 -7
  5. package/lib/src/agents.d.ts +4 -0
  6. package/lib/src/agents.js +12 -3
  7. package/lib/src/config.d.ts +7 -2
  8. package/lib/src/config.js +6 -3
  9. package/lib/src/defaults.d.ts +9 -0
  10. package/lib/src/defaults.js +29 -1
  11. package/lib/src/genie-chat.d.ts +71 -0
  12. package/lib/src/genie-chat.js +272 -0
  13. package/lib/src/genie.d.ts +2 -0
  14. package/lib/src/genie.js +11 -8
  15. package/lib/src/memory.d.ts +5 -5
  16. package/lib/src/memory.js +10 -3
  17. package/lib/src/observability.d.ts +3 -0
  18. package/lib/src/observability.js +2 -2
  19. package/lib/src/plugin.d.ts +36 -7
  20. package/lib/src/plugin.js +220 -33
  21. package/lib/src/request-context.d.ts +2 -0
  22. package/lib/src/request-context.js +3 -0
  23. package/lib/src/server.d.ts +4 -0
  24. package/lib/src/server.js +40 -2
  25. package/lib/src/statement.d.ts +16 -1
  26. package/lib/src/statement.js +50 -18
  27. package/lib/src/telemetry.d.ts +22 -1
  28. package/lib/src/telemetry.js +174 -18
  29. package/lib/src/workspaces.d.ts +2 -2
  30. package/lib/src/workspaces.js +3 -2
  31. package/lib/tsconfig.tsbuildinfo +1 -1
  32. package/package.json +32 -25
  33. package/src/agents.ts +15 -1
  34. package/src/config.ts +10 -4
  35. package/src/defaults.ts +30 -0
  36. package/src/genie-chat.ts +341 -0
  37. package/src/genie.ts +11 -7
  38. package/src/memory.ts +9 -4
  39. package/src/observability.ts +6 -2
  40. package/src/plugin.ts +262 -31
  41. package/src/request-context.ts +2 -0
  42. package/src/server.ts +35 -0
  43. package/src/statement.ts +71 -19
  44. package/src/telemetry.ts +206 -16
  45. package/src/workspaces.ts +4 -3
  46. package/exports.ts +0 -7
  47. package/lib/exports.d.ts +0 -1
  48. package/lib/exports.js +0 -2
  49. package/lib/src/openapi-tool.d.ts +0 -29
  50. package/lib/src/openapi-tool.js +0 -175
  51. package/src/openapi-tool.ts +0 -245
@@ -1,245 +0,0 @@
1
- /**
2
- * OpenAPI operation loading and JSON Schema extraction.
3
- *
4
- * @module
5
- */
6
- import { readFile } from "node:fs/promises";
7
- import { object } from "@dbx-tools/shared-core";
8
- import { urlBuilder, type UrlBuilder } from "@dbx-tools/shared-core/net";
9
- import type { JSONSchema7 } from "json-schema";
10
- import { z } from "zod";
11
-
12
- const HTTP_METHODS = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD", "TRACE"] as const;
13
-
14
- const JsonObjectSchema = z
15
- .record(z.string(), z.unknown())
16
- .describe("A JSON object embedded in an OpenAPI document.");
17
-
18
- const OpenApiMediaTypeSchema = z
19
- .object({
20
- schema: JsonObjectSchema.describe("The JSON Schema for this media type."),
21
- })
22
- .describe("One OpenAPI media type.");
23
-
24
- const OpenApiRequestBodySchema = z
25
- .object({
26
- content: z
27
- .record(z.string(), OpenApiMediaTypeSchema)
28
- .describe("Request media types keyed by content type."),
29
- })
30
- .describe("An OpenAPI request body.");
31
-
32
- const OpenApiResponseSchema = z
33
- .object({
34
- content: z
35
- .record(z.string(), OpenApiMediaTypeSchema)
36
- .optional()
37
- .describe("Response media types keyed by content type."),
38
- })
39
- .describe("One OpenAPI response.");
40
-
41
- const OpenApiOperationSchema = z
42
- .object({
43
- operationId: z.string().describe("The stable operation identifier."),
44
- summary: z.string().optional().describe("The short operation summary."),
45
- description: z.string().optional().describe("The full operation description."),
46
- requestBody: OpenApiRequestBodySchema.optional().describe(
47
- "The optional operation request body.",
48
- ),
49
- responses: z
50
- .record(z.string(), OpenApiResponseSchema)
51
- .describe("Operation responses keyed by HTTP status."),
52
- })
53
- .describe("The OpenAPI fields required to define a tool.");
54
-
55
- const OpenApiPathSchema = z
56
- .object({
57
- get: OpenApiOperationSchema.optional(),
58
- post: OpenApiOperationSchema.optional(),
59
- put: OpenApiOperationSchema.optional(),
60
- patch: OpenApiOperationSchema.optional(),
61
- delete: OpenApiOperationSchema.optional(),
62
- options: OpenApiOperationSchema.optional(),
63
- head: OpenApiOperationSchema.optional(),
64
- trace: OpenApiOperationSchema.optional(),
65
- })
66
- .describe("Operations available at one OpenAPI path.");
67
-
68
- const OpenApiDocumentSchema = z
69
- .object({
70
- paths: z
71
- .record(z.string(), OpenApiPathSchema)
72
- .refine((paths) => Object.keys(paths).length > 0, "OpenAPI paths must not be empty")
73
- .describe("OpenAPI path items keyed by URL path."),
74
- components: JsonObjectSchema.optional().describe("Reusable OpenAPI components."),
75
- servers: z
76
- .array(
77
- z.object({
78
- url: z.string().describe("Server base URL."),
79
- }),
80
- )
81
- .optional()
82
- .describe("OpenAPI server definitions."),
83
- })
84
- .describe("An OpenAPI document used to define HTTP tools.");
85
-
86
- type OpenApiDocument = z.infer<typeof OpenApiDocumentSchema>;
87
- type OpenApiOperation = z.infer<typeof OpenApiOperationSchema>;
88
-
89
- /** HTTP method supported by an {@link OpenApiTool}. */
90
- export type OpenApiHttpMethod = (typeof HTTP_METHODS)[number];
91
-
92
- /** One executable HTTP operation derived from an OpenAPI document. */
93
- export interface OpenApiTool {
94
- /** Stable operation identifier. */
95
- id: string;
96
- /** Model-facing operation description. */
97
- description: string;
98
- /** Resolved operation URL, or the OpenAPI path for a local document without a server URL. */
99
- url: string;
100
- /** HTTP method used by the operation. */
101
- method: OpenApiHttpMethod;
102
- /** JSON Schema describing operation input. */
103
- inputSchema: JSONSchema7;
104
- /** JSON Schema describing a successful operation result. */
105
- outputSchema: JSONSchema7;
106
- }
107
-
108
- /** Request options used while loading an OpenAPI document. */
109
- export interface OpenApiToolsOptions {
110
- /** Cancels an HTTP request or file read. */
111
- signal?: AbortSignal;
112
- /** Headers sent when `source` is an HTTP(S) URL. */
113
- headers?: RequestInit["headers"];
114
- }
115
-
116
- /** Load an HTTP(S) URL or local file and return its OpenAPI operations as tool schemas. */
117
- export async function openApiTools(
118
- source: string,
119
- options: OpenApiToolsOptions = {},
120
- ): Promise<OpenApiTool[]> {
121
- const sourceUrl = httpUrl(source);
122
- const document = OpenApiDocumentSchema.parse(
123
- sourceUrl
124
- ? await fetchDocument(sourceUrl, options)
125
- : await readDocument(source, options.signal),
126
- );
127
- return Object.entries(document.paths).flatMap(([path, item]) =>
128
- HTTP_METHODS.flatMap((method) => {
129
- const operation = item[method.toLowerCase() as Lowercase<OpenApiHttpMethod>];
130
- return operation ? [operationTool(document, sourceUrl, path, method, operation)] : [];
131
- }),
132
- );
133
- }
134
-
135
- function httpUrl(source: string): UrlBuilder | undefined {
136
- const value = source.trim();
137
- if (!value.startsWith("http://") && !value.startsWith("https://")) return undefined;
138
- const url = urlBuilder(value);
139
- return url?.scheme === "http" || url?.scheme === "https" ? url : undefined;
140
- }
141
-
142
- async function fetchDocument(url: URL, options: OpenApiToolsOptions): Promise<unknown> {
143
- const response = await fetch(url, {
144
- signal: options.signal,
145
- headers: options.headers,
146
- });
147
- if (!response.ok) {
148
- throw new Error(`OpenAPI request failed with HTTP ${response.status}: ${url}`);
149
- }
150
- return response.json();
151
- }
152
-
153
- async function readDocument(path: string, signal?: AbortSignal): Promise<unknown> {
154
- return JSON.parse(await readFile(path, { encoding: "utf8", signal }));
155
- }
156
-
157
- function operationTool(
158
- document: OpenApiDocument,
159
- sourceUrl: URL | undefined,
160
- path: string,
161
- method: OpenApiHttpMethod,
162
- operation: OpenApiOperation,
163
- ): OpenApiTool {
164
- const requestSchema = jsonSchema(operation.requestBody?.content) ?? { type: "object" };
165
- const responseSchema = successfulResponseSchema(operation);
166
- return {
167
- id: operation.operationId,
168
- description:
169
- operation.description?.trim() || operation.summary?.trim() || operation.operationId,
170
- url: operationUrl(document, sourceUrl, path),
171
- method,
172
- inputSchema: resolveReferences(document, requestSchema) as JSONSchema7,
173
- outputSchema: resolveReferences(document, responseSchema) as JSONSchema7,
174
- };
175
- }
176
-
177
- function successfulResponseSchema(operation: OpenApiOperation): Record<string, unknown> {
178
- for (const [status, response] of Object.entries(operation.responses)) {
179
- const schema = jsonSchema(response.content);
180
- if (/^2(?:\d{2}|XX)$/i.test(status) && schema) return schema;
181
- }
182
- return {};
183
- }
184
-
185
- function jsonSchema(
186
- content: Record<string, z.infer<typeof OpenApiMediaTypeSchema>> | undefined,
187
- ): Record<string, unknown> | undefined {
188
- const mediaType = Object.entries(content ?? {}).find(([type]) =>
189
- /^application\/(?:[^+;]+\+)?json(?:;|$)/i.test(type),
190
- );
191
- return mediaType?.[1].schema;
192
- }
193
-
194
- function operationUrl(document: OpenApiDocument, sourceUrl: URL | undefined, path: string): string {
195
- const server = document.servers?.[0]?.url;
196
- if (server) {
197
- const base = sourceUrl ? urlBuilder(new URL(server, sourceUrl)) : httpUrl(server);
198
- return base
199
- ? base.withPathAppend(path).toString()
200
- : `${server.replace(/\/$/, "")}/${path.replace(/^\//, "")}`;
201
- }
202
- return sourceUrl ? (urlBuilder(sourceUrl)?.withPathReplace(path).toString() ?? path) : path;
203
- }
204
-
205
- function resolveReferences(
206
- document: OpenApiDocument,
207
- value: unknown,
208
- active: ReadonlySet<string> = new Set(),
209
- ): unknown {
210
- if (Array.isArray(value)) return value.map((item) => resolveReferences(document, item, active));
211
- if (!object.isRecord(value)) return value;
212
- const reference = typeof value.$ref === "string" ? value.$ref : undefined;
213
- if (reference) {
214
- if (active.has(reference)) throw new Error(`Cyclic OpenAPI reference: ${reference}`);
215
- const target = referenceTarget(document, reference);
216
- const next = new Set(active).add(reference);
217
- const { $ref: _ignored, ...siblings } = value;
218
- return {
219
- ...(resolveReferences(document, target, next) as Record<string, unknown>),
220
- ...(resolveReferences(document, siblings, next) as Record<string, unknown>),
221
- };
222
- }
223
- return Object.fromEntries(
224
- Object.entries(value).map(([key, child]) => [key, resolveReferences(document, child, active)]),
225
- );
226
- }
227
-
228
- function referenceTarget(document: OpenApiDocument, reference: string): unknown {
229
- if (!reference.startsWith("#/")) throw new Error(`Unsupported OpenAPI reference: ${reference}`);
230
- let current: unknown = document;
231
- for (const rawSegment of reference.slice(2).split("/")) {
232
- const segment = rawSegment.replaceAll("~1", "/").replaceAll("~0", "~");
233
- if (!object.isRecord(current) || !(segment in current)) {
234
- throw new Error(`Unresolved OpenAPI reference: ${reference}`);
235
- }
236
- current = current[segment];
237
- }
238
- return current;
239
- }
240
-
241
- if (import.meta.main) {
242
- const source = process.argv[2];
243
- if (!source) throw new Error("Usage: bun openapi-tool.ts <openapi-url-or-file>");
244
- console.log(JSON.stringify(await openApiTools(source), null, 2));
245
- }