@redonvn/redai-openapi-generic 0.1.1

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 ADDED
@@ -0,0 +1,38 @@
1
+ # @redonvn/redai-openapi-generic
2
+
3
+ OpenClaw plugin generated from `openapi/redai/generic.json`.
4
+
5
+ ## Build
6
+
7
+ ```bash
8
+ npm run build --workspace @redonvn/redai-openapi-generic
9
+ ```
10
+
11
+ ## Install in OpenClaw
12
+
13
+ ```bash
14
+ openclaw plugins install @redonvn/redai-openapi-generic
15
+ openclaw plugins enable redai-openapi-generic
16
+ ```
17
+
18
+ ## Runtime config
19
+
20
+ Add runtime config in `~/.openclaw/openclaw.json`:
21
+
22
+ ```json5
23
+ {
24
+ "plugins": {
25
+ "entries": {
26
+ "redai-openapi-generic": {
27
+ "enabled": true,
28
+ "config": {
29
+ "baseUrl": "https://v2.redai.vn/api",
30
+ "bearerToken": "YOUR_TOKEN",
31
+ "workspaceId": "YOUR_WORKSPACE_ID",
32
+ "baseId": "YOUR_BASE_ID"
33
+ }
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ```
package/dist/index.cjs ADDED
@@ -0,0 +1,616 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ catalog: () => tool_catalog_default,
24
+ default: () => register,
25
+ spec: () => generic_default
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+ var import_promises = require("fs/promises");
29
+ var import_node_path = require("path");
30
+
31
+ // ../redai-agent-sdk/dist/index.js
32
+ var DEFAULT_BASE_URL = "https://api.redai.vn/api/v1";
33
+ var encodeQueryValue = (value) => {
34
+ if (value === void 0) {
35
+ return [];
36
+ }
37
+ if (Array.isArray(value)) {
38
+ return value.map((item) => String(item));
39
+ }
40
+ return [String(value)];
41
+ };
42
+ var headersToObject = (headers) => {
43
+ const result = {};
44
+ headers.forEach((value, key) => {
45
+ result[key] = value;
46
+ });
47
+ return result;
48
+ };
49
+ var applyPathParams = (pathTemplate, pathParams) => pathTemplate.replace(/\{([^}]+)\}/g, (_, key) => {
50
+ const raw = pathParams?.[key];
51
+ if (raw === void 0 || raw === null) {
52
+ throw new RedaiAgentError(`Missing required path parameter: ${key}`);
53
+ }
54
+ return encodeURIComponent(String(raw));
55
+ });
56
+ var buildUrl = (baseUrl, path, query) => {
57
+ const url = new URL(baseUrl);
58
+ const normalizedBasePath = url.pathname.replace(/\/+$/, "");
59
+ const normalizedRequestPath = path.startsWith("/") ? path : `/${path}`;
60
+ url.pathname = `${normalizedBasePath}${normalizedRequestPath}`.replace(/\/{2,}/g, "/");
61
+ if (query) {
62
+ for (const [key, value] of Object.entries(query)) {
63
+ for (const item of encodeQueryValue(value)) {
64
+ url.searchParams.append(key, item);
65
+ }
66
+ }
67
+ }
68
+ return url;
69
+ };
70
+ var parseResponse = async (response) => {
71
+ const contentType = response.headers.get("content-type") ?? "";
72
+ if (contentType.includes("application/json")) {
73
+ return response.json();
74
+ }
75
+ return response.text();
76
+ };
77
+ var RedaiAgentError = class extends Error {
78
+ constructor(message, options) {
79
+ super(message);
80
+ this.name = "RedaiAgentError";
81
+ this.status = options?.status;
82
+ this.body = options?.body;
83
+ }
84
+ };
85
+ var RedaiAgentClient = class {
86
+ constructor(options = {}) {
87
+ this.baseUrl = (options.baseUrl ?? DEFAULT_BASE_URL).replace(/\/$/, "");
88
+ this.bearerToken = options.bearerToken;
89
+ this.apiKey = options.apiKey;
90
+ this.apiKeyHeader = options.apiKeyHeader ?? "x-api-key";
91
+ this.defaultHeaders = options.defaultHeaders;
92
+ this.timeoutMs = options.timeoutMs;
93
+ this.fetchImpl = options.fetch ?? globalThis.fetch;
94
+ this.tenantContext = {
95
+ workspaceId: options.workspaceId,
96
+ baseId: options.baseId
97
+ };
98
+ }
99
+ createTenantHeaders(overrides) {
100
+ const workspaceId = overrides?.workspaceId ?? this.tenantContext.workspaceId;
101
+ const baseId = overrides?.baseId ?? this.tenantContext.baseId;
102
+ return {
103
+ "x-workspace-id": workspaceId,
104
+ "x-base-id": baseId
105
+ };
106
+ }
107
+ async executeTool(tool, input = {}) {
108
+ return this.request({
109
+ method: tool.method,
110
+ path: tool.path,
111
+ pathParams: input.path,
112
+ query: input.query,
113
+ headers: input.headers,
114
+ body: input.body
115
+ });
116
+ }
117
+ async request(request) {
118
+ const url = buildUrl(this.baseUrl, applyPathParams(request.path, request.pathParams), request.query);
119
+ const controller = new AbortController();
120
+ const timeout = this.timeoutMs ? setTimeout(() => controller.abort(), this.timeoutMs) : void 0;
121
+ const headers = this.buildHeaders(request.method, request.headers, request.body !== void 0);
122
+ try {
123
+ const response = await this.fetchImpl(url, {
124
+ method: request.method,
125
+ headers,
126
+ body: request.body === void 0 ? void 0 : JSON.stringify(request.body),
127
+ signal: controller.signal
128
+ });
129
+ const data = await parseResponse(response);
130
+ const result = {
131
+ ok: response.ok,
132
+ status: response.status,
133
+ statusText: response.statusText,
134
+ headers: headersToObject(response.headers),
135
+ data
136
+ };
137
+ if (!response.ok) {
138
+ throw new RedaiAgentError(`Request failed with status ${response.status}`, {
139
+ status: response.status,
140
+ body: data
141
+ });
142
+ }
143
+ return result;
144
+ } catch (error) {
145
+ if (error instanceof RedaiAgentError) {
146
+ throw error;
147
+ }
148
+ throw new RedaiAgentError("Request failed", { body: error });
149
+ } finally {
150
+ if (timeout) {
151
+ clearTimeout(timeout);
152
+ }
153
+ }
154
+ }
155
+ buildHeaders(method, requestHeaders, hasBody) {
156
+ const headers = new Headers();
157
+ for (const [key, value] of Object.entries(this.defaultHeaders ?? {})) {
158
+ headers.set(key, value);
159
+ }
160
+ for (const [key, value] of Object.entries(this.createTenantHeaders())) {
161
+ if (value !== void 0 && value !== null && value !== "") {
162
+ headers.set(key, value);
163
+ }
164
+ }
165
+ if (this.bearerToken) {
166
+ headers.set("authorization", `Bearer ${this.bearerToken}`);
167
+ } else if (this.apiKey) {
168
+ headers.set(this.apiKeyHeader ?? "x-api-key", this.apiKey);
169
+ }
170
+ for (const [key, value] of Object.entries(requestHeaders ?? {})) {
171
+ if (value !== void 0 && value !== null && value !== "") {
172
+ headers.set(key, value);
173
+ }
174
+ }
175
+ if (!headers.has("accept")) {
176
+ headers.set("accept", "application/json");
177
+ }
178
+ if (hasBody && method !== "GET" && !headers.has("content-type")) {
179
+ headers.set("content-type", "application/json");
180
+ }
181
+ return headers;
182
+ }
183
+ };
184
+
185
+ // tool-catalog.json
186
+ var tool_catalog_default = {
187
+ pluginId: "redai-openapi-generic",
188
+ pluginName: "RedAI User API Export - Generic",
189
+ version: "0.1.0",
190
+ description: "OpenAPI export cho nh\xF3m API user \u0111\xE3 ch\u1ECDn: Generic.",
191
+ serverUrl: "https://v2.redai.vn/api",
192
+ optional: true,
193
+ tools: [
194
+ {
195
+ name: "redai_openapi_generic_genericpageusercontroller_getpublishedgenericpagebypath_v1",
196
+ description: "L\u1EA5y th\xF4ng tin trang \u0111\xE3 xu\u1EA5t b\u1EA3n theo \u0111\u01B0\u1EDDng d\u1EABn",
197
+ method: "GET",
198
+ path: "/v1/user/generic-pages/by-path/{path}",
199
+ operationId: "genericpageusercontroller_getpublishedgenericpagebypath_v1",
200
+ parameters: {
201
+ type: "object",
202
+ properties: {
203
+ path: {
204
+ type: "object",
205
+ properties: {
206
+ path: {
207
+ type: "string",
208
+ description: "\u0110\u01B0\u1EDDng d\u1EABn c\u1EE7a trang"
209
+ }
210
+ },
211
+ required: [
212
+ "path"
213
+ ],
214
+ additionalProperties: false
215
+ }
216
+ },
217
+ required: [
218
+ "path"
219
+ ],
220
+ additionalProperties: false,
221
+ description: "L\u1EA5y th\xF4ng tin trang \u0111\xE3 xu\u1EA5t b\u1EA3n theo \u0111\u01B0\u1EDDng d\u1EABn tool arguments"
222
+ },
223
+ tags: [
224
+ "User Generic Page"
225
+ ]
226
+ }
227
+ ]
228
+ };
229
+
230
+ // generic.json
231
+ var generic_default = {
232
+ openapi: "3.0.0",
233
+ paths: {
234
+ "/v1/user/generic-pages/by-path/{path}": {
235
+ get: {
236
+ operationId: "GenericPageUserController_getPublishedGenericPageByPath_v1",
237
+ parameters: [
238
+ {
239
+ name: "path",
240
+ required: true,
241
+ in: "path",
242
+ description: "\u0110\u01B0\u1EDDng d\u1EABn c\u1EE7a trang",
243
+ schema: {
244
+ type: "string"
245
+ }
246
+ }
247
+ ],
248
+ responses: {
249
+ "200": {
250
+ description: "Th\xF4ng tin trang",
251
+ content: {
252
+ "application/json": {
253
+ schema: {
254
+ allOf: [
255
+ {
256
+ $ref: "#/components/schemas/ApiResponseDto"
257
+ },
258
+ {
259
+ properties: {
260
+ result: {
261
+ $ref: "#/components/schemas/UserGenericPageResponseDto"
262
+ }
263
+ }
264
+ }
265
+ ]
266
+ }
267
+ }
268
+ }
269
+ }
270
+ },
271
+ summary: "L\u1EA5y th\xF4ng tin trang \u0111\xE3 xu\u1EA5t b\u1EA3n theo \u0111\u01B0\u1EDDng d\u1EABn",
272
+ tags: [
273
+ "User Generic Page"
274
+ ]
275
+ }
276
+ }
277
+ },
278
+ info: {
279
+ title: "RedAI User API Export - Generic",
280
+ description: "OpenAPI export cho nh\xF3m API user \u0111\xE3 ch\u1ECDn: Generic.",
281
+ version: "1.0",
282
+ contact: {
283
+ name: "RedAI Support",
284
+ url: "https://redai.com/support",
285
+ email: "support@redai.com"
286
+ },
287
+ license: {
288
+ name: "MIT",
289
+ url: "https://opensource.org/licenses/MIT"
290
+ }
291
+ },
292
+ tags: [],
293
+ servers: [
294
+ {
295
+ url: "http://localhost:3000",
296
+ description: "Local Server"
297
+ },
298
+ {
299
+ url: "http://localhost:3003",
300
+ description: "Development Server"
301
+ },
302
+ {
303
+ url: "http://14.225.29.196:3003",
304
+ description: "Test Server"
305
+ },
306
+ {
307
+ url: "https://api-staging.redai.vn",
308
+ description: "Staging Server"
309
+ },
310
+ {
311
+ url: "https://v2.redai.vn/api",
312
+ description: "Production Server"
313
+ }
314
+ ],
315
+ components: {
316
+ schemas: {
317
+ ApiResponseDto: {
318
+ type: "object",
319
+ properties: {
320
+ code: {
321
+ type: "number",
322
+ description: "M\xE3 tr\u1EA1ng th\xE1i (0: Th\xE0nh c\xF4ng, kh\xE1c 0: M\xE3 l\u1ED7i c\u1EE5 th\u1EC3)",
323
+ example: 0
324
+ },
325
+ message: {
326
+ type: "string",
327
+ description: "Th\xF4ng \u0111i\u1EC7p m\xF4 t\u1EA3 k\u1EBFt qu\u1EA3",
328
+ example: "Success"
329
+ }
330
+ },
331
+ required: [
332
+ "code",
333
+ "message"
334
+ ]
335
+ },
336
+ UserGenericPageResponseDto: {
337
+ type: "object",
338
+ properties: {
339
+ id: {
340
+ type: "string",
341
+ description: "ID c\u1EE7a trang",
342
+ example: "f47ac10b-58cc-4372-a567-0e02b2c3d479"
343
+ },
344
+ name: {
345
+ type: "string",
346
+ description: "T\xEAn c\u1EE7a trang",
347
+ example: "Trang li\xEAn h\u1EC7"
348
+ },
349
+ description: {
350
+ type: "string",
351
+ description: "M\xF4 t\u1EA3 v\u1EC1 trang",
352
+ example: "Form li\xEAn h\u1EC7 cho kh\xE1ch h\xE0ng",
353
+ nullable: true
354
+ },
355
+ path: {
356
+ type: "string",
357
+ description: "\u0110\u01B0\u1EDDng d\u1EABn URL c\u1EE7a trang",
358
+ example: "lien-he"
359
+ },
360
+ config: {
361
+ type: "object",
362
+ description: "C\u1EA5u h\xECnh trang d\u1EA1ng JSON",
363
+ example: {
364
+ formId: "contact-form",
365
+ title: "Li\xEAn h\u1EC7 v\u1EDBi ch\xFAng t\xF4i",
366
+ subtitle: "H\xE3y \u0111\u1EC3 l\u1EA1i th\xF4ng tin, ch\xFAng t\xF4i s\u1EBD li\xEAn h\u1EC7 l\u1EA1i v\u1EDBi b\u1EA1n",
367
+ groups: []
368
+ }
369
+ },
370
+ publishedAt: {
371
+ type: "number",
372
+ description: "Th\u1EDDi \u0111i\u1EC3m xu\u1EA5t b\u1EA3n trang (Unix timestamp)",
373
+ example: 16733634e5
374
+ }
375
+ },
376
+ required: [
377
+ "id",
378
+ "name",
379
+ "description",
380
+ "path",
381
+ "config",
382
+ "publishedAt"
383
+ ]
384
+ }
385
+ }
386
+ },
387
+ externalDocs: {
388
+ description: "Additional Documentation",
389
+ url: "https://redai.com/docs"
390
+ },
391
+ generatedAt: "2026-03-16T08:19:30.792Z",
392
+ "x-redai-export-modules": [
393
+ "generic"
394
+ ],
395
+ "x-redai-export-scope": "user"
396
+ };
397
+
398
+ // index.ts
399
+ var DEFAULT_AUTH_STORE_PATH = "C:\\Users\\Acer\\.openclaw\\workspace-nhan-vien-redai\\auth\\redai-auth.json";
400
+ var typedCatalog = tool_catalog_default;
401
+ var formatToolResult = (payload) => ({
402
+ content: [
403
+ {
404
+ type: "text",
405
+ text: typeof payload === "string" ? payload : JSON.stringify(payload, null, 2)
406
+ }
407
+ ]
408
+ });
409
+ var resolvePluginConfig = (api) => api.config?.plugins?.entries?.[typedCatalog.pluginId]?.config ?? {};
410
+ var cloneJson = (value) => JSON.parse(JSON.stringify(value));
411
+ var removeHeadersFromSchema = (schema) => {
412
+ const cloned = cloneJson(schema ?? { type: "object", properties: {} });
413
+ const objectSchema = cloned;
414
+ if (!objectSchema.properties) {
415
+ objectSchema.properties = {};
416
+ }
417
+ delete objectSchema.properties.headers;
418
+ if (Array.isArray(objectSchema.required)) {
419
+ objectSchema.required = objectSchema.required.filter((item) => item !== "headers");
420
+ }
421
+ objectSchema.additionalProperties = false;
422
+ return objectSchema;
423
+ };
424
+ var buildAuthWrappedParameters = (tool) => {
425
+ const baseSchema = removeHeadersFromSchema(tool.parameters);
426
+ return {
427
+ ...baseSchema,
428
+ description: `${tool.description} Uses the logged-in RedAI auth for the current Telegram DM user.`,
429
+ properties: {
430
+ telegramUserId: {
431
+ type: "string",
432
+ description: "Telegram sender ID from DM metadata. The agent must derive this automatically from the current message."
433
+ },
434
+ ...baseSchema.properties ?? {}
435
+ },
436
+ required: [
437
+ "telegramUserId",
438
+ ...(baseSchema.required ?? []).filter((item) => item !== "telegramUserId")
439
+ ]
440
+ };
441
+ };
442
+ var buildAuthToolName = (toolName) => toolName.startsWith("redai_openapi_generic_") ? toolName.replace(/^redai_openapi_generic_/, "redai_openapi_generic_auth_") : "redai_openapi_generic_auth_${toolName}";
443
+ var getAuthStorePath = (runtimeConfig) => runtimeConfig.authStorePath?.trim() || DEFAULT_AUTH_STORE_PATH;
444
+ var ensureStoreDirectory = async (storePath) => {
445
+ await (0, import_promises.mkdir)((0, import_node_path.dirname)(storePath), { recursive: true });
446
+ };
447
+ var loadAuthStore = async (runtimeConfig) => {
448
+ const storePath = getAuthStorePath(runtimeConfig);
449
+ try {
450
+ const raw = await (0, import_promises.readFile)(storePath, "utf8");
451
+ const parsed = JSON.parse(raw);
452
+ return { version: 1, users: parsed?.users ?? {} };
453
+ } catch (error) {
454
+ const maybeNodeError = error;
455
+ if (maybeNodeError?.code === "ENOENT") {
456
+ await ensureStoreDirectory(storePath);
457
+ await (0, import_promises.writeFile)(storePath, JSON.stringify({ version: 1, users: {} }, null, 2), "utf8");
458
+ return { version: 1, users: {} };
459
+ }
460
+ throw error;
461
+ }
462
+ };
463
+ var getAuthStoreEntry = async (runtimeConfig, telegramUserId) => {
464
+ const store = await loadAuthStore(runtimeConfig);
465
+ return store.users[telegramUserId] ?? null;
466
+ };
467
+ var withRedaiAuth = (runtimeConfig, auth) => {
468
+ const defaultHeaders = {
469
+ ...runtimeConfig.defaultHeaders ?? {},
470
+ "x-workspace-id": auth.workspaceId
471
+ };
472
+ if (auth.baseId) {
473
+ defaultHeaders["x-base-id"] = auth.baseId;
474
+ } else {
475
+ delete defaultHeaders["x-base-id"];
476
+ }
477
+ return {
478
+ ...runtimeConfig,
479
+ bearerToken: auth.bearerToken,
480
+ apiKey: void 0,
481
+ apiKeyHeader: void 0,
482
+ defaultHeaders,
483
+ workspaceId: auth.workspaceId,
484
+ baseId: auth.baseId ?? void 0
485
+ };
486
+ };
487
+ var resolveUserRuntimeConfig = async (api, telegramUserId) => {
488
+ const runtimeConfig = resolvePluginConfig(api);
489
+ const authEntry = await getAuthStoreEntry(runtimeConfig, telegramUserId);
490
+ if (!authEntry || authEntry.status !== "active") {
491
+ return null;
492
+ }
493
+ return {
494
+ runtimeConfig,
495
+ scopedConfig: withRedaiAuth(runtimeConfig, authEntry)
496
+ };
497
+ };
498
+ var authRequiredResult = (telegramUserId) => formatToolResult({
499
+ ok: false,
500
+ status: 401,
501
+ statusText: "AUTH_REQUIRED",
502
+ data: {
503
+ message: "Ban chua dang nhap RedAI auth hop le. Hay dung /login <bearerToken> <workspaceId> [baseId] trong DM truoc khi thao tac nghiep vu.",
504
+ telegramUserId
505
+ }
506
+ });
507
+ var hasHeadersSection = (tool) => {
508
+ const parameters = tool.parameters;
509
+ return Boolean(parameters?.properties?.headers);
510
+ };
511
+ var mergeTenantHeaders = (tool, inputHeaders, runtimeConfig) => {
512
+ const entries = Object.entries(inputHeaders ?? {}).filter(([, value]) => value !== void 0 && value !== null && value !== "").map(([key, value]) => [key, String(value)]);
513
+ if (hasHeadersSection(tool)) {
514
+ if (runtimeConfig.workspaceId && !entries.some(([key]) => key.toLowerCase() === "x-workspace-id")) {
515
+ entries.push(["x-workspace-id", runtimeConfig.workspaceId]);
516
+ }
517
+ if (runtimeConfig.baseId && !entries.some(([key]) => key.toLowerCase() === "x-base-id")) {
518
+ entries.push(["x-base-id", runtimeConfig.baseId]);
519
+ }
520
+ }
521
+ return entries.length > 0 ? Object.fromEntries(entries) : void 0;
522
+ };
523
+ var executeCatalogTool = async (runtimeConfig, tool, rawParams) => {
524
+ const client = new RedaiAgentClient({
525
+ ...runtimeConfig,
526
+ baseUrl: runtimeConfig.baseUrl ?? typedCatalog.serverUrl
527
+ });
528
+ const params = rawParams ?? {};
529
+ return client.executeTool(tool, {
530
+ path: params.path,
531
+ query: params.query,
532
+ body: params.body,
533
+ headers: mergeTenantHeaders(tool, params.headers, runtimeConfig)
534
+ });
535
+ };
536
+ var registerAuthProxyTool = (api, tool) => {
537
+ api.registerTool(
538
+ {
539
+ name: buildAuthToolName(tool.name),
540
+ description: `${tool.description} Uses the logged-in RedAI auth for the current Telegram DM user.`,
541
+ parameters: buildAuthWrappedParameters(tool),
542
+ execute: async (_id, rawParams) => {
543
+ const params = rawParams ?? {};
544
+ const telegramUserId = String(params.telegramUserId ?? "");
545
+ const resolved = await resolveUserRuntimeConfig(api, telegramUserId);
546
+ if (!resolved) {
547
+ return authRequiredResult(telegramUserId);
548
+ }
549
+ const forwardedParams = { ...params };
550
+ delete forwardedParams.telegramUserId;
551
+ try {
552
+ const response = await executeCatalogTool(resolved.scopedConfig, tool, forwardedParams);
553
+ return formatToolResult(response.data);
554
+ } catch (error) {
555
+ if (error instanceof RedaiAgentError) {
556
+ return formatToolResult({
557
+ ok: false,
558
+ status: error.status ?? 500,
559
+ statusText: error.message,
560
+ data: error.body
561
+ });
562
+ }
563
+ return formatToolResult({
564
+ ok: false,
565
+ status: 500,
566
+ statusText: "PLUGIN_EXECUTION_FAILED",
567
+ data: String(error)
568
+ });
569
+ }
570
+ }
571
+ },
572
+ { optional: typedCatalog.optional ?? true }
573
+ );
574
+ };
575
+ function register(api) {
576
+ for (const tool of typedCatalog.tools) {
577
+ api.registerTool(
578
+ {
579
+ name: tool.name,
580
+ description: tool.description,
581
+ parameters: tool.parameters,
582
+ execute: async (_id, rawParams) => {
583
+ try {
584
+ const response = await executeCatalogTool(resolvePluginConfig(api), tool, rawParams);
585
+ return formatToolResult(response.data);
586
+ } catch (error) {
587
+ if (error instanceof RedaiAgentError) {
588
+ return formatToolResult({
589
+ ok: false,
590
+ status: error.status ?? 500,
591
+ statusText: error.message,
592
+ data: error.body
593
+ });
594
+ }
595
+ return formatToolResult({
596
+ ok: false,
597
+ status: 500,
598
+ statusText: "PLUGIN_EXECUTION_FAILED",
599
+ data: String(error)
600
+ });
601
+ }
602
+ }
603
+ },
604
+ { optional: typedCatalog.optional ?? true }
605
+ );
606
+ }
607
+ for (const tool of typedCatalog.tools) {
608
+ registerAuthProxyTool(api, tool);
609
+ }
610
+ }
611
+ // Annotate the CommonJS export names for ESM import in node:
612
+ 0 && (module.exports = {
613
+ catalog,
614
+ spec
615
+ });
616
+ //# sourceMappingURL=index.cjs.map