vovk 3.0.0-draft.395 → 3.0.0-draft.396

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/cjs/client/createRPC.d.ts +2 -2
  2. package/cjs/client/createRPC.js +2 -1
  3. package/cjs/client/defaultStreamHandler.js +24 -6
  4. package/cjs/client/fetcher.js +1 -1
  5. package/cjs/client/types.d.ts +2 -1
  6. package/cjs/index.d.ts +2 -2
  7. package/cjs/openapi/error.js +3 -3
  8. package/cjs/openapi/index.d.ts +5 -8
  9. package/cjs/openapi/index.js +2 -1
  10. package/cjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +2 -2
  11. package/cjs/openapi/tool.d.ts +2 -0
  12. package/cjs/openapi/tool.js +15 -0
  13. package/cjs/types.d.ts +59 -28
  14. package/cjs/types.js +3 -3
  15. package/cjs/utils/createCodeExamples.js +1 -1
  16. package/cjs/utils/createDecorator.d.ts +2 -2
  17. package/cjs/utils/createLLMTools.d.ts +12 -8
  18. package/cjs/utils/createLLMTools.js +71 -25
  19. package/cjs/utils/createStandardValidation.d.ts +4 -3
  20. package/cjs/utils/createStandardValidation.js +2 -1
  21. package/cjs/utils/createValidateOnClient.d.ts +2 -2
  22. package/cjs/utils/getJSONSchemaExample.d.ts +3 -3
  23. package/cjs/utils/getSchema.d.ts +1 -1
  24. package/cjs/utils/withValidationLibrary.d.ts +4 -3
  25. package/cjs/utils/withValidationLibrary.js +9 -8
  26. package/mjs/client/createRPC.d.ts +2 -2
  27. package/mjs/client/createRPC.js +2 -1
  28. package/mjs/client/defaultStreamHandler.js +24 -6
  29. package/mjs/client/fetcher.js +1 -1
  30. package/mjs/client/types.d.ts +2 -1
  31. package/mjs/index.d.ts +2 -2
  32. package/mjs/openapi/error.js +3 -3
  33. package/mjs/openapi/index.d.ts +5 -8
  34. package/mjs/openapi/index.js +2 -1
  35. package/mjs/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +2 -2
  36. package/mjs/openapi/tool.d.ts +2 -0
  37. package/mjs/openapi/tool.js +15 -0
  38. package/mjs/types.d.ts +59 -28
  39. package/mjs/types.js +3 -3
  40. package/mjs/utils/createCodeExamples.js +1 -1
  41. package/mjs/utils/createDecorator.d.ts +2 -2
  42. package/mjs/utils/createLLMTools.d.ts +12 -8
  43. package/mjs/utils/createLLMTools.js +71 -25
  44. package/mjs/utils/createStandardValidation.d.ts +4 -3
  45. package/mjs/utils/createStandardValidation.js +2 -1
  46. package/mjs/utils/createValidateOnClient.d.ts +2 -2
  47. package/mjs/utils/getJSONSchemaExample.d.ts +3 -3
  48. package/mjs/utils/getSchema.d.ts +1 -1
  49. package/mjs/utils/withValidationLibrary.d.ts +4 -3
  50. package/mjs/utils/withValidationLibrary.js +9 -8
  51. package/package.json +1 -1
@@ -1,3 +1,3 @@
1
- import type { KnownAny, VovkSchema } from '../types';
1
+ import type { KnownAny } from '../types';
2
2
  import type { VovkClient, VovkClientFetcher, VovkDefaultFetcherOptions } from './types';
3
- export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = Record<string, never>>(schema: VovkSchema, segmentName: string, rpcModuleName: string, fetcher?: VovkClientFetcher<OPTS>, options?: VovkDefaultFetcherOptions<OPTS>) => VovkClient<T, OPTS>;
3
+ export declare const createRPC: <T, OPTS extends Record<string, KnownAny> = Record<string, never>>(givenSchema: unknown, segmentName: string, rpcModuleName: string, fetcher?: VovkClientFetcher<OPTS>, options?: VovkDefaultFetcherOptions<OPTS>) => VovkClient<T, OPTS>;
@@ -17,7 +17,8 @@ const getHandlerPath = (endpoint, params, query) => {
17
17
  }
18
18
  return `${result}${queryStr ? '?' : ''}${queryStr}`;
19
19
  };
20
- const createRPC = (schema, segmentName, rpcModuleName, fetcher, options) => {
20
+ const createRPC = (givenSchema, segmentName, rpcModuleName, fetcher, options) => {
21
+ const schema = givenSchema; // fixes incompatibilities with JSON module
21
22
  fetcher ??= fetcher_1.fetcher;
22
23
  const segmentNamePath = options?.segmentNameOverride ?? segmentName;
23
24
  const segmentSchema = schema.segments[segmentName];
@@ -30,12 +30,14 @@ const defaultStreamHandler = async ({ response, controller, }) => {
30
30
  let value;
31
31
  try {
32
32
  let done;
33
+ if (canceled)
34
+ break;
33
35
  ({ value, done } = await reader.read());
34
36
  if (done)
35
37
  break;
36
38
  }
37
39
  catch (error) {
38
- await reader.cancel();
40
+ // await reader.cancel(); // TODO in which cases it needs to be canceled?
39
41
  const err = new Error('JSONLines stream error. ' + String(error));
40
42
  err.cause = error;
41
43
  throw err;
@@ -61,10 +63,12 @@ const defaultStreamHandler = async ({ response, controller, }) => {
61
63
  i++;
62
64
  if ('isError' in data && 'reason' in data) {
63
65
  const upcomingError = data.reason;
64
- await reader.cancel();
66
+ canceled = true;
67
+ controller.abort(data.reason);
65
68
  if (typeof upcomingError === 'string') {
66
69
  throw new Error(upcomingError);
67
70
  }
71
+ controller.abort('Stream disposed');
68
72
  throw upcomingError;
69
73
  }
70
74
  else if (!canceled) {
@@ -74,11 +78,25 @@ const defaultStreamHandler = async ({ response, controller, }) => {
74
78
  }
75
79
  }
76
80
  }
81
+ const asPromise = async () => {
82
+ const items = [];
83
+ for await (const item of asyncIterator()) {
84
+ items.push(item);
85
+ }
86
+ return items;
87
+ };
77
88
  return {
78
89
  status: response.status,
90
+ asPromise,
79
91
  [Symbol.asyncIterator]: asyncIterator,
80
- [Symbol.dispose]: () => controller.abort(),
81
- [Symbol.asyncDispose]: () => controller.abort(),
92
+ [Symbol.dispose]: () => {
93
+ canceled = true;
94
+ controller.abort('Stream disposed');
95
+ },
96
+ [Symbol.asyncDispose]: () => {
97
+ canceled = true;
98
+ controller.abort('Stream async disposed');
99
+ },
82
100
  onIterate: (cb) => {
83
101
  if (canceled)
84
102
  return () => { };
@@ -87,9 +105,9 @@ const defaultStreamHandler = async ({ response, controller, }) => {
87
105
  subscribers.delete(cb);
88
106
  };
89
107
  },
90
- abort: () => {
108
+ cancel: (reason) => {
91
109
  canceled = true;
92
- return controller.abort();
110
+ return controller.abort(reason ?? 'Stream aborted intentionally');
93
111
  },
94
112
  };
95
113
  };
@@ -58,9 +58,9 @@ function createFetcher({ prepareRequestInit, transformResponse, onSuccess, onErr
58
58
  else if (body) {
59
59
  requestInit.body = JSON.stringify(body);
60
60
  }
61
- requestInit = prepareRequestInit ? await prepareRequestInit(requestInit, inputOptions) : requestInit;
62
61
  const controller = new AbortController();
63
62
  requestInit.signal = controller.signal;
63
+ requestInit = prepareRequestInit ? await prepareRequestInit(requestInit, inputOptions) : requestInit;
64
64
  try {
65
65
  response = await fetch(endpoint, requestInit);
66
66
  }
@@ -29,11 +29,12 @@ export type StaticMethodInput<T extends ((req: VovkRequest<KnownAny, KnownAny, K
29
29
  type ToPromise<T> = T extends PromiseLike<unknown> ? T : Promise<T>;
30
30
  export type VovkStreamAsyncIterable<T> = {
31
31
  status: number;
32
+ asPromise: () => Promise<T[]>;
32
33
  [Symbol.dispose](): Promise<void> | void;
33
34
  [Symbol.asyncDispose](): Promise<void> | void;
34
35
  [Symbol.asyncIterator](): AsyncIterator<T>;
35
36
  onIterate: (cb: (data: T, i: number) => void) => () => void;
36
- abort: () => Promise<void> | void;
37
+ cancel: () => Promise<void> | void;
37
38
  };
38
39
  type StaticMethodReturn<T extends ControllerStaticMethod> = ReturnType<T> extends NextResponse<infer U> | Promise<NextResponse<infer U>> ? U : ReturnType<T> extends Response | Promise<Response> ? Awaited<ReturnType<T>> : ReturnType<T>;
39
40
  type StaticMethodReturnPromise<T extends ControllerStaticMethod> = ToPromise<StaticMethodReturn<T>>;
package/cjs/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { createVovkApp } from './createVovkApp';
2
- import { HttpStatus, HttpMethod, VovkSchemaIdEnum, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkOutput, type VovkIteration, type VovkMetaSchema, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkSchema, type VovkConfig, type VovkStrictConfig, type VovkValidationType, type VovkLLMTool, type VovkTypedMethod, type VovkSimpleJSONSchema } from './types';
2
+ import { HttpStatus, HttpMethod, VovkSchemaIdEnum, type KnownAny, type VovkErrorResponse, type VovkRequest, type VovkBody, type VovkQuery, type VovkParams, type VovkReturnType, type VovkYieldType, type VovkOutput, type VovkIteration, type VovkMetaSchema, type VovkSegmentSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkSchema, type VovkConfig, type VovkStrictConfig, type VovkValidationType, type VovkLLMTool, type VovkTypedMethod, type VovkBasicJSONSchema, type VovkOperationObject } from './types';
3
3
  import { type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkValidateOnClient, type VovkStreamAsyncIterable, createRPC, fetcher, createFetcher, progressive } from './client/index';
4
4
  import { openapi, openAPIToVovkSchema, vovkSchemaToOpenAPI } from './openapi/index';
5
5
  import { HttpException } from './HttpException';
@@ -12,7 +12,7 @@ import { multitenant } from './utils/multitenant';
12
12
  import { createLLMTools } from './utils/createLLMTools';
13
13
  import { createCodeExamples } from './utils/createCodeExamples';
14
14
  import { createValidateOnClient } from './utils/createValidateOnClient';
15
- export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkOutput, type VovkIteration, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkMetaSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkSchema, type VovkConfig, type VovkStrictConfig, type VovkValidationType, type VovkLLMTool, type VovkTypedMethod, type VovkSimpleJSONSchema, VovkSchemaIdEnum, JSONLinesResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, createFetcher, generateStaticAPI, withValidationLibrary, createStandardValidation, multitenant, createLLMTools, createCodeExamples, createValidateOnClient, progressive, openapi, openAPIToVovkSchema, vovkSchemaToOpenAPI, };
15
+ export { type KnownAny, type VovkClient, type VovkClientFetcher, type VovkDefaultFetcherOptions, type VovkStreamAsyncIterable, type VovkValidateOnClient, type VovkSegmentSchema, type VovkErrorResponse, type VovkRequest, type VovkOutput, type VovkIteration, type VovkBody, type VovkQuery, type VovkParams, type VovkYieldType, type VovkReturnType, type VovkMetaSchema, type VovkControllerSchema, type VovkHandlerSchema, type VovkSchema, type VovkConfig, type VovkStrictConfig, type VovkValidationType, type VovkLLMTool, type VovkTypedMethod, type VovkBasicJSONSchema, type VovkOperationObject, VovkSchemaIdEnum, JSONLinesResponse, HttpException, HttpStatus, HttpMethod, createVovkApp, createDecorator, createRPC, fetcher, createFetcher, generateStaticAPI, withValidationLibrary, createStandardValidation, multitenant, createLLMTools, createCodeExamples, createValidateOnClient, progressive, openapi, openAPIToVovkSchema, vovkSchemaToOpenAPI, };
16
16
  export declare const get: {
17
17
  (givenPath?: string | undefined, options?: import("./types").DecoratorOptions | undefined): (givenTarget: KnownAny, propertyKey: string) => void;
18
18
  auto: (options?: import("./types").DecoratorOptions) => (givenTarget: KnownAny, propertyKey: string) => void;
@@ -31,7 +31,7 @@ const statusDisplayText = {
31
31
  [types_1.HttpStatus.METHOD_NOT_ALLOWED]: 'Method Not Allowed',
32
32
  [types_1.HttpStatus.NOT_ACCEPTABLE]: 'Not Acceptable',
33
33
  [types_1.HttpStatus.PROXY_AUTHENTICATION_REQUIRED]: 'Proxy Authentication Required',
34
- [types_1.HttpStatus.REQUEST_TIMEOUT]: 'Request Timeout',
34
+ [types_1.HttpStatus.TRequest_TIMEOUT]: 'Request Timeout',
35
35
  [types_1.HttpStatus.CONFLICT]: 'Conflict',
36
36
  [types_1.HttpStatus.GONE]: 'Gone',
37
37
  [types_1.HttpStatus.LENGTH_REQUIRED]: 'Length Required',
@@ -39,14 +39,14 @@ const statusDisplayText = {
39
39
  [types_1.HttpStatus.PAYLOAD_TOO_LARGE]: 'Payload Too Large',
40
40
  [types_1.HttpStatus.URI_TOO_LONG]: 'URI Too Long',
41
41
  [types_1.HttpStatus.UNSUPPORTED_MEDIA_TYPE]: 'Unsupported Media Type',
42
- [types_1.HttpStatus.REQUESTED_RANGE_NOT_SATISFIABLE]: 'Requested Range Not Satisfiable',
42
+ [types_1.HttpStatus.TRequestED_RANGE_NOT_SATISFIABLE]: 'Requested Range Not Satisfiable',
43
43
  [types_1.HttpStatus.EXPECTATION_FAILED]: 'Expectation Failed',
44
44
  [types_1.HttpStatus.I_AM_A_TEAPOT]: 'I am a teapot',
45
45
  [types_1.HttpStatus.MISDIRECTED]: 'Misdirected',
46
46
  [types_1.HttpStatus.UNPROCESSABLE_ENTITY]: 'Unprocessable Entity',
47
47
  [types_1.HttpStatus.FAILED_DEPENDENCY]: 'Failed Dependency',
48
48
  [types_1.HttpStatus.PRECONDITION_REQUIRED]: 'Precondition Required',
49
- [types_1.HttpStatus.TOO_MANY_REQUESTS]: 'Too Many Requests',
49
+ [types_1.HttpStatus.TOO_MANY_TRequestS]: 'Too Many Requests',
50
50
  [types_1.HttpStatus.INTERNAL_SERVER_ERROR]: 'Internal Server Error',
51
51
  [types_1.HttpStatus.NOT_IMPLEMENTED]: 'Not Implemented',
52
52
  [types_1.HttpStatus.BAD_GATEWAY]: 'Bad Gateway',
@@ -1,12 +1,9 @@
1
- import type { OperationObject } from 'openapi3-ts/oas31';
2
1
  import { vovkSchemaToOpenAPI } from './vovkSchemaToOpenAPI';
3
2
  import { openAPIToVovkSchema } from './openAPIToVovkSchema/index';
4
- import type { KnownAny } from '../types';
5
- type OperationObjectWithCustomProperties = OperationObject & {
6
- [key in `${'x' | 'X'}-${string}`]: KnownAny;
7
- };
8
- export declare const openapiDecorator: (openAPIOperationObject?: OperationObjectWithCustomProperties | undefined) => (target: KnownAny, propertyKey: string) => void;
9
- export declare const openapi: ((openAPIOperationObject?: OperationObjectWithCustomProperties | undefined) => (target: KnownAny, propertyKey: string) => void) & {
10
- error: (status: import("../types").HttpStatus, message: string) => (target: KnownAny, propertyKey: string) => void;
3
+ import type { VovkOperationObject } from '../types';
4
+ export declare const openapiDecorator: (openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types").KnownAny, propertyKey: string) => void;
5
+ export declare const openapi: ((openAPIOperationObject?: VovkOperationObject | undefined) => (target: import("../types").KnownAny, propertyKey: string) => void) & {
6
+ error: (status: import("../types").HttpStatus, message: string) => (target: import("../types").KnownAny, propertyKey: string) => void;
7
+ tool: (toolInfo: import("../types").VovkToolInfo) => (target: import("../types").KnownAny, propertyKey: string) => void;
11
8
  };
12
9
  export { vovkSchemaToOpenAPI, openAPIToVovkSchema };
@@ -7,6 +7,7 @@ const index_1 = require("./openAPIToVovkSchema/index");
7
7
  Object.defineProperty(exports, "openAPIToVovkSchema", { enumerable: true, get: function () { return index_1.openAPIToVovkSchema; } });
8
8
  const error_1 = require("./error");
9
9
  const createDecorator_1 = require("../utils/createDecorator");
10
+ const tool_1 = require("./tool");
10
11
  exports.openapiDecorator = (0, createDecorator_1.createDecorator)(null, (openAPIOperationObject = {}) => {
11
12
  return (handlerSchema) => {
12
13
  return {
@@ -18,4 +19,4 @@ exports.openapiDecorator = (0, createDecorator_1.createDecorator)(null, (openAPI
18
19
  };
19
20
  };
20
21
  });
21
- exports.openapi = Object.assign(exports.openapiDecorator, { error: error_1.error });
22
+ exports.openapi = Object.assign(exports.openapiDecorator, { error: error_1.error, tool: tool_1.tool });
@@ -1,3 +1,3 @@
1
1
  import { ComponentsObject } from 'openapi3-ts/oas31';
2
- import { VovkSimpleJSONSchema } from '../../types';
3
- export declare function applyComponentsSchemas(schema: VovkSimpleJSONSchema, components: ComponentsObject['schemas'], mixinName: string): VovkSimpleJSONSchema | VovkSimpleJSONSchema[];
2
+ import { VovkBasicJSONSchema } from '../../types';
3
+ export declare function applyComponentsSchemas(schema: VovkBasicJSONSchema, components: ComponentsObject['schemas'], mixinName: string): VovkBasicJSONSchema | VovkBasicJSONSchema[];
@@ -0,0 +1,2 @@
1
+ import { VovkToolInfo } from '../types';
2
+ export declare const tool: (toolInfo: VovkToolInfo) => (target: import("../types").KnownAny, propertyKey: string) => void;
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.tool = void 0;
4
+ const createDecorator_1 = require("../utils/createDecorator");
5
+ exports.tool = (0, createDecorator_1.createDecorator)(null, (toolInfo) => {
6
+ return (handlerSchema) => {
7
+ return {
8
+ ...handlerSchema,
9
+ openapi: {
10
+ ...handlerSchema?.openapi,
11
+ ...Object.fromEntries(Object.entries(toolInfo).map(([key, value]) => ['x-tool-' + key, value])),
12
+ },
13
+ };
14
+ };
15
+ });
package/cjs/types.d.ts CHANGED
@@ -1,38 +1,42 @@
1
1
  import type { NextRequest } from 'next/server';
2
2
  import type { OpenAPIObject, OperationObject } from 'openapi3-ts/oas31';
3
3
  import type { JSONLinesResponse } from './JSONLinesResponse';
4
- import { VovkStreamAsyncIterable } from './client/types';
4
+ import type { VovkStreamAsyncIterable } from './client/types';
5
5
  import type { PackageJson } from 'type-fest';
6
6
  import { build } from 'tsdown';
7
7
  export type KnownAny = any;
8
8
  export type StaticClass = Function;
9
- export type VovkHandlerSchema<T = KnownAny> = {
9
+ export type VovkHandlerSchema = {
10
10
  path: string;
11
11
  httpMethod: string;
12
12
  validation?: {
13
- query?: T;
14
- body?: T;
15
- params?: T;
16
- output?: T;
17
- iteration?: T;
13
+ query?: VovkBasicJSONSchema;
14
+ body?: VovkBasicJSONSchema;
15
+ params?: VovkBasicJSONSchema;
16
+ output?: VovkBasicJSONSchema;
17
+ iteration?: VovkBasicJSONSchema;
18
18
  };
19
- openapi?: OperationObject;
19
+ openapi?: VovkOperationObject;
20
20
  misc?: Record<string, KnownAny>;
21
21
  };
22
- export type VovkControllerSchema<T = KnownAny> = {
22
+ export type VovkControllerSchema = {
23
23
  rpcModuleName: string;
24
24
  originalControllerName?: string;
25
25
  prefix?: string;
26
26
  forceApiRoot?: string;
27
- handlers: Record<string, VovkHandlerSchema<T>>;
27
+ handlers: {
28
+ [key: string]: VovkHandlerSchema;
29
+ };
28
30
  };
29
- export type VovkSegmentSchema<T = KnownAny> = {
31
+ export type VovkSegmentSchema = {
30
32
  $schema: typeof VovkSchemaIdEnum.SEGMENT | (string & {});
31
33
  emitSchema: boolean;
32
34
  segmentName: string;
33
35
  segmentType: 'segment' | 'mixin' | (string & {});
34
36
  forceApiRoot?: string;
35
- controllers: Record<string, VovkControllerSchema<T>>;
37
+ controllers: {
38
+ [key: string]: VovkControllerSchema;
39
+ };
36
40
  meta?: {
37
41
  components?: OpenAPIObject['components'];
38
42
  package?: PackageJson;
@@ -47,9 +51,11 @@ export type VovkMetaSchema = {
47
51
  openapi?: OpenAPIObject;
48
52
  [key: string]: KnownAny;
49
53
  };
50
- export type VovkSchema<T = KnownAny> = {
54
+ export type VovkSchema = {
51
55
  $schema: typeof VovkSchemaIdEnum.SCHEMA | (string & {});
52
- segments: Record<string, VovkSegmentSchema<T>>;
56
+ segments: {
57
+ [key: string]: VovkSegmentSchema;
58
+ };
53
59
  meta?: VovkMetaSchema;
54
60
  };
55
61
  export type VovkErrorResponse = {
@@ -194,7 +200,7 @@ export declare enum HttpStatus {
194
200
  METHOD_NOT_ALLOWED = 405,
195
201
  NOT_ACCEPTABLE = 406,
196
202
  PROXY_AUTHENTICATION_REQUIRED = 407,
197
- REQUEST_TIMEOUT = 408,
203
+ TRequest_TIMEOUT = 408,
198
204
  CONFLICT = 409,
199
205
  GONE = 410,
200
206
  LENGTH_REQUIRED = 411,
@@ -202,14 +208,14 @@ export declare enum HttpStatus {
202
208
  PAYLOAD_TOO_LARGE = 413,
203
209
  URI_TOO_LONG = 414,
204
210
  UNSUPPORTED_MEDIA_TYPE = 415,
205
- REQUESTED_RANGE_NOT_SATISFIABLE = 416,
211
+ TRequestED_RANGE_NOT_SATISFIABLE = 416,
206
212
  EXPECTATION_FAILED = 417,
207
213
  I_AM_A_TEAPOT = 418,
208
214
  MISDIRECTED = 421,
209
215
  UNPROCESSABLE_ENTITY = 422,
210
216
  FAILED_DEPENDENCY = 424,
211
217
  PRECONDITION_REQUIRED = 428,
212
- TOO_MANY_REQUESTS = 429,
218
+ TOO_MANY_TRequestS = 429,
213
219
  INTERNAL_SERVER_ERROR = 500,
214
220
  NOT_IMPLEMENTED = 501,
215
221
  BAD_GATEWAY = 502,
@@ -222,13 +228,17 @@ export interface VovkLLMTool {
222
228
  body?: KnownAny;
223
229
  query?: KnownAny;
224
230
  params?: KnownAny;
225
- }, options: KnownAny) => Promise<KnownAny>;
231
+ }, options?: KnownAny) => Promise<KnownAny>;
226
232
  name: string;
227
233
  description: string;
228
234
  parameters?: {
229
235
  type: 'object';
230
- properties?: Record<string, KnownAny>;
231
- required?: string[];
236
+ properties?: {
237
+ body?: VovkBasicJSONSchema;
238
+ query?: VovkBasicJSONSchema;
239
+ params?: VovkBasicJSONSchema;
240
+ };
241
+ required?: ('body' | 'query' | 'params')[];
232
242
  additionalProperties?: boolean;
233
243
  };
234
244
  models: {
@@ -240,24 +250,30 @@ export interface VovkLLMTool {
240
250
  } | undefined;
241
251
  type: 'function';
242
252
  }
243
- export type VovkSimpleJSONSchema = {
253
+ export type VovkBasicJSONSchema = {
244
254
  $schema?: string;
245
255
  type?: string | string[];
246
256
  format?: string;
247
257
  $ref?: string;
248
- items?: VovkSimpleJSONSchema;
258
+ items?: VovkBasicJSONSchema;
249
259
  enum?: KnownAny[];
250
260
  title?: string;
251
261
  description?: string;
252
- properties?: Record<string, VovkSimpleJSONSchema>;
262
+ properties?: {
263
+ [key: string]: VovkBasicJSONSchema;
264
+ };
253
265
  required?: string[];
254
266
  examples?: KnownAny[];
255
- $defs?: Record<string, VovkSimpleJSONSchema>;
256
- definitions?: Record<string, VovkSimpleJSONSchema>;
267
+ $defs?: {
268
+ [key: string]: VovkBasicJSONSchema;
269
+ };
270
+ definitions?: {
271
+ [key: string]: VovkBasicJSONSchema;
272
+ };
257
273
  additionalProperties?: boolean;
258
- anyOf?: VovkSimpleJSONSchema[];
259
- oneOf?: VovkSimpleJSONSchema[];
260
- allOf?: VovkSimpleJSONSchema[];
274
+ anyOf?: VovkBasicJSONSchema[];
275
+ oneOf?: VovkBasicJSONSchema[];
276
+ allOf?: VovkBasicJSONSchema[];
261
277
  const?: KnownAny;
262
278
  example?: KnownAny;
263
279
  contentEncoding?: string;
@@ -266,6 +282,21 @@ export type VovkSimpleJSONSchema = {
266
282
  maxLength?: number;
267
283
  [key: `x-${string}`]: KnownAny;
268
284
  };
285
+ export type VovkOperationObject = OperationObject & {
286
+ 'x-tool-disable'?: boolean;
287
+ 'x-tool-description'?: string;
288
+ 'x-tool-successMessage'?: string;
289
+ 'x-tool-errorMessage'?: string;
290
+ 'x-tool-includeResponse'?: boolean;
291
+ };
292
+ export type VovkToolInfo = {
293
+ disable?: boolean;
294
+ description?: string;
295
+ successMessage?: string;
296
+ errorMessage?: string;
297
+ includeResponse?: boolean;
298
+ [key: string]: KnownAny;
299
+ };
269
300
  export declare enum VovkSchemaIdEnum {
270
301
  META = "https://vovk.dev/api/schema/v3/meta.json",
271
302
  CONFIG = "https://vovk.dev/api/schema/v3/config.json",
package/cjs/types.js CHANGED
@@ -41,7 +41,7 @@ var HttpStatus;
41
41
  HttpStatus[HttpStatus["METHOD_NOT_ALLOWED"] = 405] = "METHOD_NOT_ALLOWED";
42
42
  HttpStatus[HttpStatus["NOT_ACCEPTABLE"] = 406] = "NOT_ACCEPTABLE";
43
43
  HttpStatus[HttpStatus["PROXY_AUTHENTICATION_REQUIRED"] = 407] = "PROXY_AUTHENTICATION_REQUIRED";
44
- HttpStatus[HttpStatus["REQUEST_TIMEOUT"] = 408] = "REQUEST_TIMEOUT";
44
+ HttpStatus[HttpStatus["TRequest_TIMEOUT"] = 408] = "TRequest_TIMEOUT";
45
45
  HttpStatus[HttpStatus["CONFLICT"] = 409] = "CONFLICT";
46
46
  HttpStatus[HttpStatus["GONE"] = 410] = "GONE";
47
47
  HttpStatus[HttpStatus["LENGTH_REQUIRED"] = 411] = "LENGTH_REQUIRED";
@@ -49,14 +49,14 @@ var HttpStatus;
49
49
  HttpStatus[HttpStatus["PAYLOAD_TOO_LARGE"] = 413] = "PAYLOAD_TOO_LARGE";
50
50
  HttpStatus[HttpStatus["URI_TOO_LONG"] = 414] = "URI_TOO_LONG";
51
51
  HttpStatus[HttpStatus["UNSUPPORTED_MEDIA_TYPE"] = 415] = "UNSUPPORTED_MEDIA_TYPE";
52
- HttpStatus[HttpStatus["REQUESTED_RANGE_NOT_SATISFIABLE"] = 416] = "REQUESTED_RANGE_NOT_SATISFIABLE";
52
+ HttpStatus[HttpStatus["TRequestED_RANGE_NOT_SATISFIABLE"] = 416] = "TRequestED_RANGE_NOT_SATISFIABLE";
53
53
  HttpStatus[HttpStatus["EXPECTATION_FAILED"] = 417] = "EXPECTATION_FAILED";
54
54
  HttpStatus[HttpStatus["I_AM_A_TEAPOT"] = 418] = "I_AM_A_TEAPOT";
55
55
  HttpStatus[HttpStatus["MISDIRECTED"] = 421] = "MISDIRECTED";
56
56
  HttpStatus[HttpStatus["UNPROCESSABLE_ENTITY"] = 422] = "UNPROCESSABLE_ENTITY";
57
57
  HttpStatus[HttpStatus["FAILED_DEPENDENCY"] = 424] = "FAILED_DEPENDENCY";
58
58
  HttpStatus[HttpStatus["PRECONDITION_REQUIRED"] = 428] = "PRECONDITION_REQUIRED";
59
- HttpStatus[HttpStatus["TOO_MANY_REQUESTS"] = 429] = "TOO_MANY_REQUESTS";
59
+ HttpStatus[HttpStatus["TOO_MANY_TRequestS"] = 429] = "TOO_MANY_TRequestS";
60
60
  HttpStatus[HttpStatus["INTERNAL_SERVER_ERROR"] = 500] = "INTERNAL_SERVER_ERROR";
61
61
  HttpStatus[HttpStatus["NOT_IMPLEMENTED"] = 501] = "NOT_IMPLEMENTED";
62
62
  HttpStatus[HttpStatus["BAD_GATEWAY"] = 502] = "BAD_GATEWAY";
@@ -148,7 +148,7 @@ ${outputValidation ? `print(response)\n${getPySample(outputValidation, 0)}` : ''
148
148
  function generateRustCode({ handlerName, rpcName, packageName, queryValidation, bodyValidation, paramsValidation, outputValidation, iterationValidation, }) {
149
149
  const getRsJSONSample = (schema, indent) => (0, getJSONSchemaExample_1.getJSONSchemaExample)(schema, { stripQuotes: false, indent: indent ?? 4 });
150
150
  const getRsOutputSample = (schema, indent) => (0, getJSONSchemaExample_1.getJSONSchemaExample)(schema, { stripQuotes: true, indent: indent ?? 4 });
151
- /* const getRsFormSample = (schema: VovkSimpleJSONSchema, indent?: number, nesting = 0) => {
151
+ /* const getRsFormSample = (schema: VovkBasicJSONSchema, indent?: number, nesting = 0) => {
152
152
  let formSample = 'let form = multipart::Form::new()';
153
153
  for (const [key, prop] of Object.entries(schema.properties || {})) {
154
154
  const target = prop.oneOf?.[0] || prop.anyOf?.[0] || prop.allOf?.[0] || prop;
@@ -1,6 +1,6 @@
1
1
  import type { VovkHandlerSchema, KnownAny, VovkController, VovkRequest } from '../types';
2
2
  type Next = () => Promise<unknown>;
3
- export declare function createDecorator<ARGS extends unknown[], REQUEST = VovkRequest>(handler: null | ((this: VovkController, req: REQUEST, next: Next, ...args: ARGS) => unknown), initHandler?: (this: VovkController, ...args: ARGS) => Omit<VovkHandlerSchema, 'path' | 'httpMethod'> | ((handlerSchema: VovkHandlerSchema | null, options: {
3
+ export declare function createDecorator<TArgs extends unknown[], TRequest = VovkRequest>(handler: null | ((this: VovkController, req: TRequest, next: Next, ...args: TArgs) => unknown), initHandler?: (this: VovkController, ...args: TArgs) => Omit<VovkHandlerSchema, 'path' | 'httpMethod'> | ((handlerSchema: VovkHandlerSchema | null, options: {
4
4
  handlerName: string;
5
- }) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: ARGS) => (target: KnownAny, propertyKey: string) => void;
5
+ }) => Omit<Partial<VovkHandlerSchema>, 'path' | 'httpMethod'>) | null | undefined): (...args: TArgs) => (target: KnownAny, propertyKey: string) => void;
6
6
  export {};
@@ -1,14 +1,14 @@
1
- import type { KnownAny, VovkHandlerSchema, VovkLLMTool } from '../types';
1
+ import type { KnownAny, VovkHandlerSchema, VovkLLMTool, VovkBasicJSONSchema } from '../types';
2
2
  type Handler = ((...args: KnownAny[]) => KnownAny) & {
3
3
  fn?: (input: KnownAny) => KnownAny;
4
4
  isRPC?: boolean;
5
5
  schema?: VovkHandlerSchema;
6
6
  models?: {
7
- body?: KnownAny;
8
- query?: KnownAny;
9
- params?: KnownAny;
10
- output?: KnownAny;
11
- iteration?: KnownAny;
7
+ body?: VovkBasicJSONSchema;
8
+ query?: VovkBasicJSONSchema;
9
+ params?: VovkBasicJSONSchema;
10
+ output?: VovkBasicJSONSchema;
11
+ iteration?: VovkBasicJSONSchema;
12
12
  };
13
13
  };
14
14
  type CallerInput = {
@@ -28,17 +28,21 @@ type CallerInput = {
28
28
  meta: Record<string, KnownAny> | undefined;
29
29
  handlerName: string;
30
30
  moduleName: string;
31
+ resultFormatter: typeof defaultResultFormatter;
31
32
  };
32
- declare function defaultCaller({ handler, body, query, params, init, meta }: CallerInput, _options: KnownAny): Promise<any>;
33
- export declare function createLLMTools({ modules, caller, meta, onExecute, onError, }: {
33
+ declare function defaultCaller({ handler, body, query, params, init, meta, resultFormatter, schema }: CallerInput, _options: KnownAny): Promise<[any, null] | [any, Error]>;
34
+ declare function defaultResultFormatter(result: KnownAny, _schema: VovkHandlerSchema): Promise<any>;
35
+ export declare function createLLMTools({ modules, caller, meta, resultFormatter, onExecute, onError, }: {
34
36
  modules: Record<string, object | [object, {
35
37
  init?: RequestInit;
36
38
  }]>;
37
39
  caller?: typeof defaultCaller;
38
40
  meta?: Record<string, KnownAny>;
41
+ resultFormatter?: typeof defaultResultFormatter | null | 'mcp';
39
42
  onExecute?: (result: KnownAny, callerInput: CallerInput, options: KnownAny) => void;
40
43
  onError?: (error: Error, callerInput: CallerInput, options: KnownAny) => void;
41
44
  }): {
42
45
  tools: VovkLLMTool[];
46
+ toolsByName: Record<string, VovkLLMTool>;
43
47
  };
44
48
  export {};
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createLLMTools = createLLMTools;
4
- const createLLMTool = ({ moduleName, handlerName, caller, module, init, meta, onExecute, onError, }) => {
4
+ const createLLMTool = ({ moduleName, handlerName, caller, module, init, meta, resultFormatter, onExecute, onError, }) => {
5
5
  if (!module) {
6
6
  throw new Error(`Module "${moduleName}" not found.`);
7
7
  }
@@ -13,7 +13,7 @@ const createLLMTool = ({ moduleName, handlerName, caller, module, init, meta, on
13
13
  if (!schema || !schema.openapi) {
14
14
  throw new Error(`Handler "${handlerName}" in module "${moduleName}" does not have a valid schema.`);
15
15
  }
16
- const execute = (input, options) => {
16
+ const execute = async (input, options) => {
17
17
  const { body, query, params } = input;
18
18
  const callerInput = {
19
19
  schema,
@@ -26,10 +26,16 @@ const createLLMTool = ({ moduleName, handlerName, caller, module, init, meta, on
26
26
  meta,
27
27
  handlerName,
28
28
  moduleName,
29
+ resultFormatter,
29
30
  };
30
- return caller(callerInput, options)
31
- .then((data) => onExecute(data, callerInput, options) ?? data)
32
- .catch((error) => onError?.(error, callerInput, options) ?? error);
31
+ const [result, error] = await caller(callerInput, options);
32
+ if (error) {
33
+ onError?.(error, callerInput, options);
34
+ }
35
+ else {
36
+ onExecute(result, callerInput, options);
37
+ }
38
+ return result;
33
39
  };
34
40
  const parametersProperties = {
35
41
  ...(schema?.validation?.body
@@ -63,30 +69,63 @@ const createLLMTool = ({ moduleName, handlerName, caller, module, init, meta, on
63
69
  models,
64
70
  };
65
71
  };
66
- async function defaultCaller({ handler, body, query, params, init, meta },
72
+ async function defaultCaller({ handler, body, query, params, init, meta, resultFormatter, schema },
67
73
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
68
74
  _options) {
69
- if (handler.isRPC) {
70
- return handler({
71
- handler,
72
- body,
73
- query,
74
- params,
75
- init,
76
- meta,
77
- });
75
+ if (!handler.isRPC && !handler.fn) {
76
+ throw new Error('Handler is not a valid RPC or controller method');
78
77
  }
79
- if (handler.fn) {
80
- return handler.fn({
81
- body,
82
- query,
83
- params,
84
- meta,
85
- });
78
+ try {
79
+ let result;
80
+ if (handler.isRPC) {
81
+ result = await handler({
82
+ handler,
83
+ body,
84
+ query,
85
+ params,
86
+ init,
87
+ meta,
88
+ });
89
+ }
90
+ if (handler.fn) {
91
+ result = await handler.fn({
92
+ body,
93
+ query,
94
+ params,
95
+ meta,
96
+ });
97
+ }
98
+ return [resultFormatter(result, schema), null];
99
+ }
100
+ catch (e) {
101
+ return [resultFormatter(e, schema), e];
86
102
  }
87
- throw new Error('Handler is not a valid RPC or controller method');
88
103
  }
89
- function createLLMTools({ modules, caller = defaultCaller, meta, onExecute = (result) => result, onError = () => { }, }) {
104
+ async function mcpResultFormatter(result, schema) {
105
+ const successMessage = schema?.openapi?.['x-tool-successMessage'] ?? 'Tool executed successfully.';
106
+ const errorMessage = schema?.openapi?.['x-tool-errorMessage'] ?? 'An error occurred while executing the tool.';
107
+ const includeResponse = schema?.openapi?.['x-tool-includeResponse'] ?? true;
108
+ return {
109
+ content: [
110
+ {
111
+ type: 'text',
112
+ text: [
113
+ result instanceof Error ? errorMessage : successMessage,
114
+ includeResponse
115
+ ? `${result instanceof Error ? 'Error' : 'Result'}:\n${JSON.stringify(result, null, 2)}`
116
+ : null,
117
+ ]
118
+ .filter(Boolean)
119
+ .join('\n\n'),
120
+ },
121
+ ],
122
+ };
123
+ }
124
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
125
+ async function defaultResultFormatter(result, _schema) {
126
+ return result;
127
+ }
128
+ function createLLMTools({ modules, caller = defaultCaller, meta, resultFormatter, onExecute = (result) => result, onError = () => { }, }) {
90
129
  const moduleWithConfig = modules;
91
130
  const tools = Object.entries(moduleWithConfig ?? {})
92
131
  .map(([moduleName, moduleWithconfig]) => {
@@ -99,7 +138,7 @@ function createLLMTools({ modules, caller = defaultCaller, meta, onExecute = (re
99
138
  module = moduleWithconfig;
100
139
  }
101
140
  return Object.entries(module ?? {})
102
- .filter(([, handler]) => handler?.schema?.openapi && !handler?.schema?.openapi?.['x-tool-exclude'])
141
+ .filter(([, handler]) => handler?.schema?.openapi && !handler?.schema?.openapi?.['x-tool-disable'])
103
142
  .map(([handlerName]) => createLLMTool({
104
143
  moduleName,
105
144
  handlerName,
@@ -107,12 +146,19 @@ function createLLMTools({ modules, caller = defaultCaller, meta, onExecute = (re
107
146
  module,
108
147
  init,
109
148
  meta,
149
+ resultFormatter: resultFormatter
150
+ ? resultFormatter === 'mcp'
151
+ ? mcpResultFormatter
152
+ : resultFormatter
153
+ : defaultResultFormatter,
110
154
  onExecute,
111
155
  onError,
112
156
  }));
113
157
  })
114
158
  .flat();
159
+ const toolsByName = Object.fromEntries(tools.map((tool) => [tool.name, tool]));
115
160
  return {
116
161
  tools,
162
+ toolsByName,
117
163
  };
118
164
  }