vovk 3.0.0-draft.99 → 3.0.2
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 +23 -12
- package/bin/index.mjs +10 -0
- package/dist/client/createRPC.d.ts +13 -3
- package/dist/client/createRPC.js +112 -50
- package/dist/client/defaultHandler.d.ts +5 -1
- package/dist/client/defaultHandler.js +12 -9
- package/dist/client/defaultStreamHandler.d.ts +16 -4
- package/dist/client/defaultStreamHandler.js +262 -62
- package/dist/client/fetcher.d.ts +41 -3
- package/dist/client/fetcher.js +125 -60
- package/dist/client/progressive.d.ts +15 -0
- package/dist/client/progressive.js +56 -0
- package/dist/{utils → client}/serializeQuery.d.ts +2 -2
- package/dist/{utils → client}/serializeQuery.js +2 -5
- package/dist/core/HttpException.d.ts +16 -0
- package/dist/core/HttpException.js +26 -0
- package/dist/core/JSONLinesResponder.d.ts +42 -0
- package/dist/core/JSONLinesResponder.js +94 -0
- package/dist/core/controllersToStaticParams.d.ts +13 -0
- package/dist/core/controllersToStaticParams.js +32 -0
- package/dist/core/createDecorator.d.ts +18 -0
- package/dist/core/createDecorator.js +60 -0
- package/dist/core/decorators.d.ts +66 -0
- package/dist/core/decorators.js +155 -0
- package/dist/core/getSchema.d.ts +21 -0
- package/dist/core/getSchema.js +31 -0
- package/dist/core/initSegment.d.ts +33 -0
- package/dist/core/initSegment.js +35 -0
- package/dist/core/multitenant.d.ts +33 -0
- package/dist/core/multitenant.js +132 -0
- package/dist/core/resolveGeneratorConfigValues.d.ts +19 -0
- package/dist/core/resolveGeneratorConfigValues.js +59 -0
- package/dist/{utils → core}/setHandlerSchema.d.ts +2 -2
- package/dist/{utils → core}/setHandlerSchema.js +1 -4
- package/dist/core/toDownloadResponse.d.ts +11 -0
- package/dist/core/toDownloadResponse.js +25 -0
- package/dist/core/vovkApp.d.ts +36 -0
- package/dist/core/vovkApp.js +318 -0
- package/dist/index.d.ts +25 -59
- package/dist/index.js +23 -23
- package/dist/internal.d.ts +17 -0
- package/dist/internal.js +10 -0
- package/dist/openapi/error.d.ts +6 -0
- package/dist/openapi/error.js +97 -0
- package/dist/openapi/openAPIToVovkSchema/applyComponentsSchemas.d.ts +3 -0
- package/dist/openapi/openAPIToVovkSchema/applyComponentsSchemas.js +65 -0
- package/dist/openapi/openAPIToVovkSchema/index.d.ts +5 -0
- package/dist/openapi/openAPIToVovkSchema/index.js +153 -0
- package/dist/openapi/openAPIToVovkSchema/inlineRefs.d.ts +9 -0
- package/dist/openapi/openAPIToVovkSchema/inlineRefs.js +99 -0
- package/dist/openapi/operation.d.ts +26 -0
- package/dist/openapi/operation.js +19 -0
- package/dist/openapi/tool.d.ts +6 -0
- package/dist/openapi/tool.js +12 -0
- package/dist/openapi/vovkSchemaToOpenAPI.d.ts +21 -0
- package/dist/openapi/vovkSchemaToOpenAPI.js +250 -0
- package/dist/req/bufferBody.d.ts +1 -0
- package/dist/req/bufferBody.js +30 -0
- package/dist/req/parseBody.d.ts +4 -0
- package/dist/req/parseBody.js +49 -0
- package/dist/req/parseForm.d.ts +1 -0
- package/dist/req/parseForm.js +24 -0
- package/dist/{utils → req}/parseQuery.d.ts +1 -2
- package/dist/{utils → req}/parseQuery.js +12 -12
- package/dist/req/reqMeta.d.ts +2 -0
- package/dist/{utils → req}/reqMeta.js +1 -4
- package/dist/req/reqQuery.d.ts +2 -0
- package/dist/req/reqQuery.js +4 -0
- package/dist/req/validateContentType.d.ts +1 -0
- package/dist/req/validateContentType.js +32 -0
- package/dist/samples/createCodeSamples.d.ts +20 -0
- package/dist/samples/createCodeSamples.js +293 -0
- package/dist/samples/objectToCode.d.ts +8 -0
- package/dist/samples/objectToCode.js +38 -0
- package/dist/samples/schemaToCode.d.ts +11 -0
- package/dist/samples/schemaToCode.js +264 -0
- package/dist/samples/schemaToObject.d.ts +2 -0
- package/dist/samples/schemaToObject.js +164 -0
- package/dist/samples/schemaToTsType.d.ts +2 -0
- package/dist/samples/schemaToTsType.js +114 -0
- package/dist/tools/ToModelOutput.d.ts +8 -0
- package/dist/tools/ToModelOutput.js +10 -0
- package/dist/tools/createTool.d.ts +126 -0
- package/dist/tools/createTool.js +6 -0
- package/dist/tools/createToolFactory.d.ts +135 -0
- package/dist/tools/createToolFactory.js +62 -0
- package/dist/tools/deriveTools.d.ts +46 -0
- package/dist/tools/deriveTools.js +132 -0
- package/dist/tools/toModelOutputDefault.d.ts +7 -0
- package/dist/tools/toModelOutputDefault.js +7 -0
- package/dist/tools/toModelOutputMCP.d.ts +30 -0
- package/dist/tools/toModelOutputMCP.js +54 -0
- package/dist/tsconfig.tsbuildinfo +1 -0
- package/dist/types/client.d.ts +139 -0
- package/dist/types/client.js +1 -0
- package/dist/types/config.d.ts +151 -0
- package/dist/types/config.js +1 -0
- package/dist/types/core.d.ts +115 -0
- package/dist/types/core.js +1 -0
- package/dist/types/enums.d.ts +75 -0
- package/dist/{types.js → types/enums.js} +21 -9
- package/dist/types/inference.d.ts +117 -0
- package/dist/types/inference.js +1 -0
- package/dist/types/json-schema.d.ts +51 -0
- package/dist/types/json-schema.js +1 -0
- package/dist/types/operation.d.ts +5 -0
- package/dist/types/operation.js +1 -0
- package/dist/types/package.d.ts +544 -0
- package/dist/types/package.js +5 -0
- package/dist/types/request.d.ts +48 -0
- package/dist/types/request.js +1 -0
- package/dist/types/standard-schema.d.ts +117 -0
- package/dist/types/standard-schema.js +6 -0
- package/dist/types/tools.d.ts +43 -0
- package/dist/types/tools.js +1 -0
- package/dist/types/utils.d.ts +9 -0
- package/dist/types/utils.js +1 -0
- package/dist/types/validation.d.ts +48 -0
- package/dist/types/validation.js +1 -0
- package/dist/utils/camelCase.d.ts +6 -0
- package/dist/utils/camelCase.js +34 -0
- package/dist/utils/deepExtend.d.ts +54 -0
- package/dist/utils/deepExtend.js +127 -0
- package/dist/utils/fileNameToDisposition.d.ts +1 -0
- package/dist/utils/fileNameToDisposition.js +3 -0
- package/dist/utils/shim.d.ts +1 -0
- package/dist/utils/shim.js +1 -1
- package/dist/utils/toKebabCase.d.ts +1 -0
- package/dist/utils/toKebabCase.js +5 -0
- package/dist/utils/trimPath.d.ts +1 -0
- package/dist/utils/trimPath.js +1 -0
- package/dist/utils/upperFirst.d.ts +1 -0
- package/dist/utils/upperFirst.js +3 -0
- package/dist/validation/createStandardValidation.d.ts +268 -0
- package/dist/validation/createStandardValidation.js +45 -0
- package/dist/validation/createValidateOnClient.d.ts +14 -0
- package/dist/validation/createValidateOnClient.js +23 -0
- package/dist/validation/procedure.d.ts +261 -0
- package/dist/validation/procedure.js +8 -0
- package/dist/validation/withValidationLibrary.d.ts +119 -0
- package/dist/validation/withValidationLibrary.js +174 -0
- package/package.json +45 -11
- package/dist/HttpException.d.ts +0 -7
- package/dist/HttpException.js +0 -15
- package/dist/StreamJSONResponse.d.ts +0 -14
- package/dist/StreamJSONResponse.js +0 -57
- package/dist/VovkApp.d.ts +0 -29
- package/dist/VovkApp.js +0 -188
- package/dist/client/index.d.ts +0 -3
- package/dist/client/index.js +0 -7
- package/dist/client/types.d.ts +0 -104
- package/dist/client/types.js +0 -2
- package/dist/createDecorator.d.ts +0 -6
- package/dist/createDecorator.js +0 -43
- package/dist/createVovkApp.d.ts +0 -62
- package/dist/createVovkApp.js +0 -118
- package/dist/types.d.ts +0 -220
- package/dist/utils/generateStaticAPI.d.ts +0 -4
- package/dist/utils/generateStaticAPI.js +0 -18
- package/dist/utils/getSchema.d.ts +0 -20
- package/dist/utils/getSchema.js +0 -33
- package/dist/utils/reqForm.d.ts +0 -2
- package/dist/utils/reqForm.js +0 -13
- package/dist/utils/reqMeta.d.ts +0 -2
- package/dist/utils/reqQuery.d.ts +0 -2
- package/dist/utils/reqQuery.js +0 -10
- package/dist/utils/withValidation.d.ts +0 -20
- package/dist/utils/withValidation.js +0 -72
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { DefaultModelOutput } from './toModelOutputDefault.js';
|
|
2
|
+
import type { VovkRequest } from '../types/request.js';
|
|
3
|
+
import type { VovkToolDerived, ToModelOutputFn } from '../types/tools.js';
|
|
4
|
+
type DerivedToolInput = {
|
|
5
|
+
body?: unknown;
|
|
6
|
+
query?: unknown;
|
|
7
|
+
params?: unknown;
|
|
8
|
+
};
|
|
9
|
+
type DeriveToolsBaseOptions<TOutput = unknown, TFormattedOutput = unknown> = {
|
|
10
|
+
modules: Record<string, object>;
|
|
11
|
+
meta?: Record<string, unknown>;
|
|
12
|
+
onExecute?: (result: unknown, tool: VovkToolDerived<DerivedToolInput, TOutput, TFormattedOutput>, req: Pick<VovkRequest, 'vovk'> | null) => void;
|
|
13
|
+
onError?: (error: Error, tool: VovkToolDerived<DerivedToolInput, TOutput, TFormattedOutput>, req: Pick<VovkRequest, 'vovk'> | null) => void;
|
|
14
|
+
};
|
|
15
|
+
type DeriveToolsResult<TOutput, TFormattedOutput> = {
|
|
16
|
+
tools: VovkToolDerived<DerivedToolInput, TOutput, TFormattedOutput>[];
|
|
17
|
+
toolsByName: Record<string, VovkToolDerived<DerivedToolInput, TOutput, TFormattedOutput>>;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Derives AI tools from controllers and RPC modules.
|
|
21
|
+
* @see https://vovk.dev/tools
|
|
22
|
+
* @example
|
|
23
|
+
* ```ts
|
|
24
|
+
* import { deriveTools, ToModelOutput } from 'vovk';
|
|
25
|
+
* import { UserRPC } from 'vovk-client';
|
|
26
|
+
*
|
|
27
|
+
* // Derive AI tools from the UserRPC module
|
|
28
|
+
* const { tools, toolsByName } = deriveTools({
|
|
29
|
+
* modules: { UserRPC },
|
|
30
|
+
* toModelOutput: ToModelOutput.MCP,
|
|
31
|
+
* onExecute: (result, tool) => {
|
|
32
|
+
* console.log(`Tool ${tool.name} executed successfully.`);
|
|
33
|
+
* },
|
|
34
|
+
* onError: (error, tool) => {
|
|
35
|
+
* console.error(`Tool ${tool.name} execution failed:`, error);
|
|
36
|
+
* },
|
|
37
|
+
* });
|
|
38
|
+
* ```
|
|
39
|
+
*/
|
|
40
|
+
export declare function deriveTools<TOutput = unknown, TFormattedOutput = DefaultModelOutput<TOutput>>(options: DeriveToolsBaseOptions & {
|
|
41
|
+
toModelOutput?: never;
|
|
42
|
+
}): DeriveToolsResult<TOutput, TFormattedOutput>;
|
|
43
|
+
export declare function deriveTools<TOutput = unknown, TFormattedOutput = unknown>(options: DeriveToolsBaseOptions & {
|
|
44
|
+
toModelOutput: ToModelOutputFn<unknown, TOutput, TFormattedOutput>;
|
|
45
|
+
}): DeriveToolsResult<TOutput, TFormattedOutput>;
|
|
46
|
+
export {};
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import { ToModelOutput } from './ToModelOutput.js';
|
|
2
|
+
async function caller({ handler, handlerName, body, query, params, meta, toModelOutput }, tool) {
|
|
3
|
+
if (!handler.isRPC && !handler.fn) {
|
|
4
|
+
throw new Error('Handler is not a valid RPC or controller method');
|
|
5
|
+
}
|
|
6
|
+
try {
|
|
7
|
+
let result;
|
|
8
|
+
let req = null;
|
|
9
|
+
if (handler.isRPC) {
|
|
10
|
+
result = await handler({
|
|
11
|
+
handler,
|
|
12
|
+
body,
|
|
13
|
+
query,
|
|
14
|
+
params,
|
|
15
|
+
meta,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
else if (handler.fn) {
|
|
19
|
+
[result, req] = await handler.fn({
|
|
20
|
+
body,
|
|
21
|
+
query,
|
|
22
|
+
params,
|
|
23
|
+
meta,
|
|
24
|
+
transform: (result, req) => [result, req],
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
throw new Error(`Unable to call handler "${handlerName}". It's neither RPC nor controller method with "fn" interface.`);
|
|
29
|
+
}
|
|
30
|
+
return [
|
|
31
|
+
await toModelOutput(result, tool, req),
|
|
32
|
+
req,
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
catch (e) {
|
|
36
|
+
return [await toModelOutput(e, tool, null), null];
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const makeTool = ({ moduleName, handlerName, module, meta, toModelOutput, onExecute, onError, }) => {
|
|
40
|
+
if (!module) {
|
|
41
|
+
throw new Error(`Module "${moduleName}" not found.`);
|
|
42
|
+
}
|
|
43
|
+
const handler = module[handlerName];
|
|
44
|
+
if (!handler) {
|
|
45
|
+
throw new Error(`Handler "${handlerName}" not found in module "${moduleName}".`);
|
|
46
|
+
}
|
|
47
|
+
const { schema, definition } = handler;
|
|
48
|
+
const inputSchemas = Object.fromEntries(['body', 'query', 'params'].map((key) => [key, definition?.[key]]).filter(([, value]) => Boolean(value)));
|
|
49
|
+
if (!schema || !schema.operationObject) {
|
|
50
|
+
throw new Error(`Handler "${handlerName}" in module "${moduleName}" does not have a valid schema.`);
|
|
51
|
+
}
|
|
52
|
+
const execute = async (input) => {
|
|
53
|
+
const { body, query, params } = input;
|
|
54
|
+
const callerInput = {
|
|
55
|
+
schema,
|
|
56
|
+
inputSchemas,
|
|
57
|
+
handler,
|
|
58
|
+
body,
|
|
59
|
+
query,
|
|
60
|
+
params,
|
|
61
|
+
meta,
|
|
62
|
+
handlerName,
|
|
63
|
+
moduleName,
|
|
64
|
+
toModelOutput,
|
|
65
|
+
};
|
|
66
|
+
const [result, req] = await caller(callerInput, tool);
|
|
67
|
+
if (result instanceof Error) {
|
|
68
|
+
onError(result, tool, req);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
onExecute(result, tool, req);
|
|
72
|
+
}
|
|
73
|
+
return result;
|
|
74
|
+
};
|
|
75
|
+
const parametersProperties = {
|
|
76
|
+
...(schema?.validation?.body
|
|
77
|
+
? {
|
|
78
|
+
body: schema.validation.body,
|
|
79
|
+
}
|
|
80
|
+
: {}),
|
|
81
|
+
...(schema?.validation?.query
|
|
82
|
+
? {
|
|
83
|
+
query: schema.validation.query,
|
|
84
|
+
}
|
|
85
|
+
: {}),
|
|
86
|
+
...(schema?.validation?.params
|
|
87
|
+
? {
|
|
88
|
+
params: schema.validation.params,
|
|
89
|
+
}
|
|
90
|
+
: {}),
|
|
91
|
+
};
|
|
92
|
+
const tool = {
|
|
93
|
+
type: 'function',
|
|
94
|
+
execute,
|
|
95
|
+
name: schema.operationObject?.['x-tool']?.name ?? `${moduleName}_${handlerName}`,
|
|
96
|
+
inputSchema: undefined,
|
|
97
|
+
outputSchema: definition?.output,
|
|
98
|
+
title: schema.operationObject?.['x-tool']?.title ?? schema.operationObject?.summary,
|
|
99
|
+
description: schema.operationObject?.['x-tool']?.description ??
|
|
100
|
+
([schema.operationObject?.summary ?? '', schema.operationObject?.description ?? ''].filter(Boolean).join('\n') ||
|
|
101
|
+
handlerName),
|
|
102
|
+
parameters: {
|
|
103
|
+
type: 'object',
|
|
104
|
+
properties: parametersProperties,
|
|
105
|
+
required: Object.keys(parametersProperties),
|
|
106
|
+
additionalProperties: false,
|
|
107
|
+
},
|
|
108
|
+
inputSchemas,
|
|
109
|
+
};
|
|
110
|
+
return tool;
|
|
111
|
+
};
|
|
112
|
+
export function deriveTools(options) {
|
|
113
|
+
const { modules, meta, toModelOutput = ToModelOutput.DEFAULT, onExecute = (result) => result, onError = () => { }, } = options;
|
|
114
|
+
const tools = Object.entries(modules ?? {}).flatMap(([moduleName, module]) => {
|
|
115
|
+
return Object.entries(module ?? {})
|
|
116
|
+
.filter(([, handler]) => handler?.schema?.operationObject && !handler?.schema?.operationObject?.['x-tool']?.hidden)
|
|
117
|
+
.map(([handlerName]) => makeTool({
|
|
118
|
+
moduleName,
|
|
119
|
+
handlerName,
|
|
120
|
+
module,
|
|
121
|
+
meta,
|
|
122
|
+
toModelOutput,
|
|
123
|
+
onExecute,
|
|
124
|
+
onError,
|
|
125
|
+
}));
|
|
126
|
+
});
|
|
127
|
+
const toolsByName = Object.fromEntries(tools.map((tool) => [tool.name, tool]));
|
|
128
|
+
return {
|
|
129
|
+
tools,
|
|
130
|
+
toolsByName,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { VovkRequest } from '../types/request.js';
|
|
2
|
+
import type { VovkTool } from '../types/tools.js';
|
|
3
|
+
export type DefaultModelOutput<T> = T | {
|
|
4
|
+
error: string;
|
|
5
|
+
};
|
|
6
|
+
export type ToModelOutputDefaultFn = <TInput, TOutput>(result: TOutput | Error, tool: VovkTool<TInput, TOutput, unknown>, req: Pick<VovkRequest, 'vovk'> | null) => DefaultModelOutput<TOutput>;
|
|
7
|
+
export declare const toModelOutputDefault: ToModelOutputDefaultFn;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export const toModelOutputDefault = (result,
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
_tool,
|
|
4
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
5
|
+
_req) => {
|
|
6
|
+
return result instanceof Error ? { error: result.message } : result;
|
|
7
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { VovkRequest } from '../types/request.js';
|
|
2
|
+
import type { VovkTool } from '../types/tools.js';
|
|
3
|
+
export type MCPModelOutput = {
|
|
4
|
+
content: [
|
|
5
|
+
{
|
|
6
|
+
type: 'audio';
|
|
7
|
+
mimeType: string;
|
|
8
|
+
data: string;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'image';
|
|
11
|
+
mimeType: string;
|
|
12
|
+
data: string;
|
|
13
|
+
} | {
|
|
14
|
+
type: 'text';
|
|
15
|
+
text: string;
|
|
16
|
+
}
|
|
17
|
+
];
|
|
18
|
+
annotations?: {
|
|
19
|
+
audience?: ('user' | 'assistant')[];
|
|
20
|
+
priority?: number;
|
|
21
|
+
lastModified?: string;
|
|
22
|
+
};
|
|
23
|
+
structuredContent?: {
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
};
|
|
26
|
+
isError?: boolean;
|
|
27
|
+
};
|
|
28
|
+
type ToModelOutputMCPFn = <TOutput>(result: TOutput | Error, tool: VovkTool, req: Pick<VovkRequest, 'vovk'> | null) => Promise<MCPModelOutput>;
|
|
29
|
+
export declare const toModelOutputMCP: ToModelOutputMCPFn;
|
|
30
|
+
export {};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { reqMeta } from '../req/reqMeta.js';
|
|
2
|
+
// converts array to object with "items" key for MCP structured content
|
|
3
|
+
const structuredContentToObject = (data) => {
|
|
4
|
+
if (Array.isArray(data)) {
|
|
5
|
+
return { items: data };
|
|
6
|
+
}
|
|
7
|
+
return data;
|
|
8
|
+
};
|
|
9
|
+
const toBase64 = (buf) => typeof Buffer !== 'undefined'
|
|
10
|
+
? Buffer.from(buf).toString('base64')
|
|
11
|
+
: btoa([...new Uint8Array(buf)].map((b) => String.fromCharCode(b)).join(''));
|
|
12
|
+
async function responseToMCP(res) {
|
|
13
|
+
const mimeType = res.headers.get('Content-Type')?.split(';')[0].trim() || '';
|
|
14
|
+
if (mimeType.startsWith('audio/')) {
|
|
15
|
+
return { content: [{ type: 'audio', mimeType, data: toBase64(await res.arrayBuffer()) }] };
|
|
16
|
+
}
|
|
17
|
+
if (mimeType.startsWith('image/')) {
|
|
18
|
+
return { content: [{ type: 'image', mimeType, data: toBase64(await res.arrayBuffer()) }] };
|
|
19
|
+
}
|
|
20
|
+
if (mimeType === 'application/json') {
|
|
21
|
+
const structuredContent = await res.json();
|
|
22
|
+
return {
|
|
23
|
+
content: [{ type: 'text', text: JSON.stringify(structuredContent) }],
|
|
24
|
+
structuredContent: structuredContentToObject(structuredContent),
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (mimeType.startsWith('text/') || /xml|javascript|yaml/.test(mimeType)) {
|
|
28
|
+
return { content: [{ type: 'text', text: await res.text() }] };
|
|
29
|
+
}
|
|
30
|
+
return {
|
|
31
|
+
content: [{ type: 'text', text: `Unsupported response content type ${mimeType}` }],
|
|
32
|
+
isError: true,
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
export const toModelOutputMCP = async (result, _tool, req) => {
|
|
36
|
+
const mcpOutputMeta = req ? reqMeta(req).mcpOutput : null;
|
|
37
|
+
if (result instanceof Response) {
|
|
38
|
+
return { ...(await responseToMCP(result)), ...(mcpOutputMeta || {}) };
|
|
39
|
+
}
|
|
40
|
+
const isError = result instanceof Error;
|
|
41
|
+
return {
|
|
42
|
+
content: [
|
|
43
|
+
{
|
|
44
|
+
type: 'text',
|
|
45
|
+
text: isError ? result.message : JSON.stringify(result),
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
...(isError ? { isError: true } : {}),
|
|
49
|
+
...(!isError && typeof result === 'object' && result !== null
|
|
50
|
+
? { structuredContent: structuredContentToObject(result) }
|
|
51
|
+
: {}),
|
|
52
|
+
...(mcpOutputMeta || {}),
|
|
53
|
+
};
|
|
54
|
+
};
|