@krak-stack/registry 0.1.13 → 0.1.15
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 +19 -0
- package/dist/components/ui/app-brand.d.ts +18 -13
- package/dist/components/ui/app-brand.js +48 -15
- package/dist/components/ui/code-block.js +10 -6
- package/dist/components/ui/copy-button.d.ts +1 -1
- package/dist/components/ui/copy-button.js +1 -1
- package/dist/components/ui/data-table.d.ts +1 -1
- package/dist/components/ui/data-table.js +21 -20
- package/dist/components/ui/effect-form.js +7 -6
- package/dist/components/ui/file-picker.js +2 -1
- package/dist/components/ui/form.js +17 -15
- package/dist/components/ui/google-map.d.ts +6 -10
- package/dist/components/ui/google-map.js +19 -14
- package/dist/components/ui/locale-switcher.js +7 -1
- package/dist/components/ui/sidebar-layout.js +19 -21
- package/dist/components/ui/theme-switcher.js +1 -1
- package/dist/lib/docs-core.js +165 -109
- package/dist/lib/documentation-toolkit.d.ts +1 -1
- package/dist/lib/documentation-toolkit.js +41 -40
- package/dist/lib/httpapi-cli.d.ts +6 -6
- package/dist/lib/httpapi-cli.js +83 -48
- package/dist/lib/httpapi-client.d.ts +11 -2
- package/dist/lib/httpapi-client.js +29 -9
- package/dist/lib/httpapi-helpers.d.ts +15 -21
- package/dist/lib/httpapi-helpers.js +38 -26
- package/dist/lib/httpapi-mcp.js +81 -50
- package/dist/lib/httpapi-toolkit.d.ts +3 -2
- package/dist/lib/httpapi-toolkit.js +101 -65
- package/dist/lib/seo.js +29 -17
- package/dist/oxlint/anti-slop/index.js +1592 -0
- package/dist/services/agent/client/atom.d.ts +7 -7
- package/dist/services/agent/client/index.js +100 -62
- package/dist/services/agent/index.d.ts +71 -71
- package/dist/services/agent/index.js +38 -19
- package/dist/services/notification/channels/index.d.ts +11 -9
- package/dist/services/notification/channels/ses/index.d.ts +6 -6
- package/dist/services/notification/channels/ses/index.js +15 -11
- package/dist/services/notification/client/index.js +3 -2
- package/dist/services/notification/client/notification-menu.d.ts +9 -9
- package/dist/services/notification/index.d.ts +7 -6
- package/dist/services/notification/public.js +3 -2
- package/dist/services/s3/index.d.ts +2 -16
- package/dist/services/s3/index.js +12 -9
- package/package.json +7 -1
|
@@ -9,25 +9,25 @@ import {
|
|
|
9
9
|
SchemaRepresentation
|
|
10
10
|
} from "effect";
|
|
11
11
|
import { HttpApi, OpenApi } from "effect/unstable/httpapi";
|
|
12
|
-
var JsonObjectSchema = Schema.Record(Schema.String, Schema.
|
|
12
|
+
var JsonObjectSchema = Schema.Record(Schema.String, Schema.Json).annotate({
|
|
13
13
|
identifier: "HttpJsonObject",
|
|
14
14
|
title: "HTTP JSON object",
|
|
15
15
|
description: "A JSON object passed to an HTTP API operation.",
|
|
16
16
|
examples: [{ id: "example-id" }]
|
|
17
17
|
});
|
|
18
18
|
var JsonObjectFromString = Schema.fromJsonString(JsonObjectSchema);
|
|
19
|
-
var JsonValueFromString = Schema.fromJsonString(Schema.
|
|
19
|
+
var JsonValueFromString = Schema.fromJsonString(Schema.Json);
|
|
20
20
|
var JsonSchemaAnnotations = Schema.Struct({
|
|
21
21
|
title: Schema.optional(Schema.String),
|
|
22
22
|
description: Schema.optional(Schema.String),
|
|
23
|
-
examples: Schema.optional(Schema.Array(Schema.
|
|
23
|
+
examples: Schema.optional(Schema.Array(Schema.Json))
|
|
24
24
|
}).annotate({
|
|
25
25
|
identifier: "HttpJsonSchemaAnnotations",
|
|
26
26
|
title: "HTTP JSON Schema annotations",
|
|
27
27
|
description: "JSON Schema annotations surfaced on generated tool inputs."
|
|
28
28
|
});
|
|
29
29
|
var HttpApiToolInputSchema = Schema.Struct({
|
|
30
|
-
body: Schema.optional(Schema.
|
|
30
|
+
body: Schema.optional(Schema.Json)
|
|
31
31
|
}).annotate({
|
|
32
32
|
identifier: "HttpApiToolInput",
|
|
33
33
|
title: "HTTP API tool input",
|
|
@@ -41,6 +41,8 @@ var HttpApiMethods = [
|
|
|
41
41
|
"patch",
|
|
42
42
|
"delete"
|
|
43
43
|
];
|
|
44
|
+
var HttpApiOperationSchema = Schema.declare((value) => Schema.is(JsonObjectSchema)(value)).annotate({ identifier: "HttpApiOperation" });
|
|
45
|
+
var decodeHttpApiOperation = Schema.decodeUnknownOption(HttpApiOperationSchema);
|
|
44
46
|
var toHttpError = (message, error) => new Error(message, { cause: error });
|
|
45
47
|
var sanitizeHttpName = (name) => name.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
46
48
|
var httpApiToolName = (method, path, operation) => {
|
|
@@ -54,9 +56,10 @@ var httpApiOperations = ({
|
|
|
54
56
|
const operations = [];
|
|
55
57
|
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
56
58
|
for (const method of methods) {
|
|
57
|
-
const operation = pathItem[method];
|
|
58
|
-
if (operation)
|
|
59
|
-
operations.push({ method, path, operation });
|
|
59
|
+
const operation = decodeHttpApiOperation(pathItem[method]);
|
|
60
|
+
if (Option.isSome(operation)) {
|
|
61
|
+
operations.push({ method, path, operation: operation.value });
|
|
62
|
+
}
|
|
60
63
|
}
|
|
61
64
|
}
|
|
62
65
|
return operations;
|
|
@@ -85,30 +88,36 @@ var schemaWithVisibleAnnotations = (schema) => {
|
|
|
85
88
|
...acc,
|
|
86
89
|
...decodeAnnotations(item).pipe(Option.getOrElse(() => ({})))
|
|
87
90
|
}), directAnnotations);
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
const visible = { ...schema };
|
|
92
|
+
if ("title" in annotations && !("title" in schema)) {
|
|
93
|
+
visible.title = annotations.title;
|
|
94
|
+
}
|
|
95
|
+
if ("description" in annotations && !("description" in schema)) {
|
|
96
|
+
visible.description = annotations.description;
|
|
97
|
+
}
|
|
98
|
+
if ("examples" in annotations && !("examples" in schema)) {
|
|
99
|
+
visible.examples = annotations.examples;
|
|
100
|
+
}
|
|
101
|
+
return visible;
|
|
94
102
|
};
|
|
95
103
|
var referencedDefinitions = (schema, definitions) => {
|
|
96
104
|
const names = new Set;
|
|
97
|
-
const pending = [schema];
|
|
105
|
+
const pending = [Schema.decodeUnknownSync(Schema.Json)(schema)];
|
|
98
106
|
while (pending.length > 0) {
|
|
99
107
|
const current = pending.pop();
|
|
100
|
-
if (!current || typeof current !== "object")
|
|
101
|
-
continue;
|
|
102
108
|
if (Array.isArray(current)) {
|
|
103
109
|
pending.push(...current);
|
|
104
110
|
continue;
|
|
105
111
|
}
|
|
106
|
-
|
|
107
|
-
|
|
112
|
+
const record = Schema.decodeUnknownOption(Schema.Record(Schema.String, Schema.Json))(current);
|
|
113
|
+
if (Option.isNone(record))
|
|
114
|
+
continue;
|
|
115
|
+
for (const [key, value] of Object.entries(record.value)) {
|
|
116
|
+
if (key === "$ref" && Schema.is(Schema.String)(value)) {
|
|
108
117
|
const name = value.match(/^#\/(?:\$defs|components\/schemas)\/(.+)$/)?.[1];
|
|
109
118
|
if (name && !names.has(name) && definitions[name]) {
|
|
110
119
|
names.add(name);
|
|
111
|
-
pending.push(definitions[name]);
|
|
120
|
+
pending.push(Schema.decodeUnknownSync(Schema.Json)(definitions[name]));
|
|
112
121
|
}
|
|
113
122
|
} else if (key !== "$defs") {
|
|
114
123
|
pending.push(value);
|
|
@@ -131,10 +140,12 @@ var httpApiOperationInputSchema = (operation) => {
|
|
|
131
140
|
...queryParameters,
|
|
132
141
|
...headerParameters
|
|
133
142
|
]) {
|
|
134
|
-
|
|
135
|
-
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
136
|
-
...parameter.description ? { description: parameter.description } : {}
|
|
143
|
+
const property = {
|
|
144
|
+
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
137
145
|
};
|
|
146
|
+
if (parameter.description)
|
|
147
|
+
property.description = parameter.description;
|
|
148
|
+
properties[parameter.name] = property;
|
|
138
149
|
if (parameter.required)
|
|
139
150
|
required.push(parameter.name);
|
|
140
151
|
}
|
|
@@ -200,10 +211,11 @@ class HttpApiSpec extends Context.Service()("HttpApiSpec", {
|
|
|
200
211
|
});
|
|
201
212
|
const definitions = document.definitions ?? {};
|
|
202
213
|
const usedDefinitions = referencedDefinitions(document.schema, definitions);
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
}
|
|
214
|
+
const result = { ...document.schema };
|
|
215
|
+
if (Object.keys(usedDefinitions).length > 0) {
|
|
216
|
+
result.$defs = usedDefinitions;
|
|
217
|
+
}
|
|
218
|
+
return result;
|
|
207
219
|
};
|
|
208
220
|
return {
|
|
209
221
|
info: spec.info,
|
package/dist/lib/httpapi-mcp.js
CHANGED
|
@@ -1,18 +1,34 @@
|
|
|
1
1
|
// ../../src/lib/httpapi-mcp.ts
|
|
2
|
-
import { Context as Context3, Effect as Effect3, Layer as Layer3, Option as Option2, Schema as
|
|
2
|
+
import { Context as Context3, Effect as Effect3, Layer as Layer3, Option as Option2, Schema as Schema3 } from "effect";
|
|
3
3
|
import { McpSchema, McpServer } from "effect/unstable/ai";
|
|
4
4
|
|
|
5
5
|
// ../../src/lib/httpapi-client.ts
|
|
6
|
-
import { Context, Effect, Layer } from "effect";
|
|
6
|
+
import { Context, Effect, Layer, Schema } from "effect";
|
|
7
7
|
import { HttpClient } from "effect/unstable/http";
|
|
8
8
|
import {
|
|
9
9
|
HttpApiClient as EffectHttpApiClient
|
|
10
10
|
} from "effect/unstable/httpapi";
|
|
11
|
+
var HttpApiOperationResultValue = Schema.suspend(() => Schema.Union([
|
|
12
|
+
Schema.Null,
|
|
13
|
+
Schema.String,
|
|
14
|
+
Schema.Number,
|
|
15
|
+
Schema.Boolean,
|
|
16
|
+
Schema.DateFromString,
|
|
17
|
+
Schema.Uint8ArrayFromBase64,
|
|
18
|
+
Schema.Array(HttpApiOperationResultValue),
|
|
19
|
+
Schema.Record(Schema.String, HttpApiOperationResultValue)
|
|
20
|
+
]));
|
|
21
|
+
var HttpApiOperationResult = Schema.Union([
|
|
22
|
+
HttpApiOperationResultValue,
|
|
23
|
+
Schema.Undefined
|
|
24
|
+
]).annotate({ identifier: "HttpApiOperationResult" });
|
|
25
|
+
var encodeHttpApiOperationResult = Effect.fn("HttpApiClient.encodeOperationResult")((result) => Schema.encodeUnknownEffect(HttpApiOperationResult)(result).pipe(Effect.map((encoded) => encoded ?? null), Effect.mapError((cause) => new Error("HTTP API result is not serializable", { cause }))));
|
|
26
|
+
var GeneratedOperation = Schema.declare((value) => value instanceof Function).annotate({ identifier: "GeneratedOperation" });
|
|
27
|
+
var GeneratedOperationEffect = Schema.declare((value) => Effect.isEffect(value)).annotate({ identifier: "GeneratedOperationEffect" });
|
|
11
28
|
var makeGeneratedClient = (api, http, baseUrl) => EffectHttpApiClient.makeWith(api, {
|
|
12
29
|
baseUrl,
|
|
13
30
|
httpClient: http
|
|
14
31
|
});
|
|
15
|
-
var isClientEffect = (value) => Effect.isEffect(value);
|
|
16
32
|
var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperation")(function* (client, { input, operation: entry }) {
|
|
17
33
|
const operationId = entry.operation.operationId;
|
|
18
34
|
if (!operationId) {
|
|
@@ -20,22 +36,23 @@ var executeGeneratedOperation = Effect.fn("HttpApiClient.executeGeneratedOperati
|
|
|
20
36
|
}
|
|
21
37
|
const target = Object(client);
|
|
22
38
|
const groupName = Object.keys(target).filter((name) => operationId.startsWith(`${name}.`)).sort((a, b) => b.length - a.length)[0];
|
|
23
|
-
const group = groupName ?
|
|
39
|
+
const group = groupName ? Object.entries(target).find(([name]) => name === groupName)?.[1] : target;
|
|
24
40
|
const endpointName = groupName ? operationId.slice(groupName.length + 1) : operationId;
|
|
25
|
-
const
|
|
26
|
-
|
|
41
|
+
const endpointCandidate = group instanceof Function ? undefined : Object.entries(Object(group)).find(([name]) => name === endpointName)?.[1];
|
|
42
|
+
const endpoint = Schema.decodeUnknownOption(GeneratedOperation)(endpointCandidate);
|
|
43
|
+
if (endpoint._tag === "None") {
|
|
27
44
|
return yield* Effect.fail(new Error(`No generated API client operation for ${operationId}`));
|
|
28
45
|
}
|
|
29
|
-
const result = endpoint({
|
|
46
|
+
const result = Schema.decodeUnknownOption(GeneratedOperationEffect)(endpoint.value({
|
|
30
47
|
headers: input.headers,
|
|
31
48
|
params: input.params,
|
|
32
49
|
query: input.query,
|
|
33
50
|
payload: input.body
|
|
34
|
-
});
|
|
35
|
-
if (
|
|
51
|
+
}));
|
|
52
|
+
if (result._tag === "None") {
|
|
36
53
|
return yield* Effect.fail(new Error(`Generated API client operation ${operationId} is invalid`));
|
|
37
54
|
}
|
|
38
|
-
return yield* result;
|
|
55
|
+
return yield* result.value;
|
|
39
56
|
});
|
|
40
57
|
|
|
41
58
|
class ApiClient extends Context.Service()("ApiClient") {
|
|
@@ -43,6 +60,7 @@ class ApiClient extends Context.Service()("ApiClient") {
|
|
|
43
60
|
const http = yield* HttpClient.HttpClient;
|
|
44
61
|
const client = yield* makeGeneratedClient(config.api, http, config.baseUrl);
|
|
45
62
|
return {
|
|
63
|
+
encodeResult: config.encodeResult ?? ((result) => encodeHttpApiOperationResult(result)),
|
|
46
64
|
execute: Effect.fn("ApiClient.execute")(function* (options) {
|
|
47
65
|
return yield* executeGeneratedOperation(client, options);
|
|
48
66
|
})
|
|
@@ -57,29 +75,29 @@ import {
|
|
|
57
75
|
JsonSchema,
|
|
58
76
|
Layer as Layer2,
|
|
59
77
|
Option,
|
|
60
|
-
Schema,
|
|
78
|
+
Schema as Schema2,
|
|
61
79
|
SchemaRepresentation
|
|
62
80
|
} from "effect";
|
|
63
81
|
import { HttpApi as HttpApi2, OpenApi } from "effect/unstable/httpapi";
|
|
64
|
-
var JsonObjectSchema =
|
|
82
|
+
var JsonObjectSchema = Schema2.Record(Schema2.String, Schema2.Json).annotate({
|
|
65
83
|
identifier: "HttpJsonObject",
|
|
66
84
|
title: "HTTP JSON object",
|
|
67
85
|
description: "A JSON object passed to an HTTP API operation.",
|
|
68
86
|
examples: [{ id: "example-id" }]
|
|
69
87
|
});
|
|
70
|
-
var JsonObjectFromString =
|
|
71
|
-
var JsonValueFromString =
|
|
72
|
-
var JsonSchemaAnnotations =
|
|
73
|
-
title:
|
|
74
|
-
description:
|
|
75
|
-
examples:
|
|
88
|
+
var JsonObjectFromString = Schema2.fromJsonString(JsonObjectSchema);
|
|
89
|
+
var JsonValueFromString = Schema2.fromJsonString(Schema2.Json);
|
|
90
|
+
var JsonSchemaAnnotations = Schema2.Struct({
|
|
91
|
+
title: Schema2.optional(Schema2.String),
|
|
92
|
+
description: Schema2.optional(Schema2.String),
|
|
93
|
+
examples: Schema2.optional(Schema2.Array(Schema2.Json))
|
|
76
94
|
}).annotate({
|
|
77
95
|
identifier: "HttpJsonSchemaAnnotations",
|
|
78
96
|
title: "HTTP JSON Schema annotations",
|
|
79
97
|
description: "JSON Schema annotations surfaced on generated tool inputs."
|
|
80
98
|
});
|
|
81
|
-
var HttpApiToolInputSchema =
|
|
82
|
-
body:
|
|
99
|
+
var HttpApiToolInputSchema = Schema2.Struct({
|
|
100
|
+
body: Schema2.optional(Schema2.Json)
|
|
83
101
|
}).annotate({
|
|
84
102
|
identifier: "HttpApiToolInput",
|
|
85
103
|
title: "HTTP API tool input",
|
|
@@ -93,6 +111,8 @@ var HttpApiMethods = [
|
|
|
93
111
|
"patch",
|
|
94
112
|
"delete"
|
|
95
113
|
];
|
|
114
|
+
var HttpApiOperationSchema = Schema2.declare((value) => Schema2.is(JsonObjectSchema)(value)).annotate({ identifier: "HttpApiOperation" });
|
|
115
|
+
var decodeHttpApiOperation = Schema2.decodeUnknownOption(HttpApiOperationSchema);
|
|
96
116
|
var toHttpError = (message, error) => new Error(message, { cause: error });
|
|
97
117
|
var httpApiToolName = (method, path, operation) => {
|
|
98
118
|
const fallback = `${method}_${path.replace(/^\/api\//, "").replace(/[/:{}]/g, "_")}`;
|
|
@@ -105,9 +125,10 @@ var httpApiOperations = ({
|
|
|
105
125
|
const operations = [];
|
|
106
126
|
for (const [path, pathItem] of Object.entries(spec.paths)) {
|
|
107
127
|
for (const method of methods) {
|
|
108
|
-
const operation = pathItem[method];
|
|
109
|
-
if (operation)
|
|
110
|
-
operations.push({ method, path, operation });
|
|
128
|
+
const operation = decodeHttpApiOperation(pathItem[method]);
|
|
129
|
+
if (Option.isSome(operation)) {
|
|
130
|
+
operations.push({ method, path, operation: operation.value });
|
|
131
|
+
}
|
|
111
132
|
}
|
|
112
133
|
}
|
|
113
134
|
return operations;
|
|
@@ -128,7 +149,7 @@ var httpApiToolEntries = Effect2.fn("Http.toolEntries")(function* (operations) {
|
|
|
128
149
|
catch: (error) => error instanceof Error ? error : new Error(String(error))
|
|
129
150
|
});
|
|
130
151
|
});
|
|
131
|
-
var decodeAnnotations =
|
|
152
|
+
var decodeAnnotations = Schema2.decodeUnknownOption(JsonSchemaAnnotations);
|
|
132
153
|
var schemaWithVisibleAnnotations = (schema) => {
|
|
133
154
|
const directAnnotations = decodeAnnotations(schema).pipe(Option.getOrElse(() => ({})));
|
|
134
155
|
const allOf = Array.isArray(schema.allOf) ? schema.allOf : [];
|
|
@@ -136,30 +157,36 @@ var schemaWithVisibleAnnotations = (schema) => {
|
|
|
136
157
|
...acc,
|
|
137
158
|
...decodeAnnotations(item).pipe(Option.getOrElse(() => ({})))
|
|
138
159
|
}), directAnnotations);
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
160
|
+
const visible = { ...schema };
|
|
161
|
+
if ("title" in annotations && !("title" in schema)) {
|
|
162
|
+
visible.title = annotations.title;
|
|
163
|
+
}
|
|
164
|
+
if ("description" in annotations && !("description" in schema)) {
|
|
165
|
+
visible.description = annotations.description;
|
|
166
|
+
}
|
|
167
|
+
if ("examples" in annotations && !("examples" in schema)) {
|
|
168
|
+
visible.examples = annotations.examples;
|
|
169
|
+
}
|
|
170
|
+
return visible;
|
|
145
171
|
};
|
|
146
172
|
var referencedDefinitions = (schema, definitions) => {
|
|
147
173
|
const names = new Set;
|
|
148
|
-
const pending = [schema];
|
|
174
|
+
const pending = [Schema2.decodeUnknownSync(Schema2.Json)(schema)];
|
|
149
175
|
while (pending.length > 0) {
|
|
150
176
|
const current = pending.pop();
|
|
151
|
-
if (!current || typeof current !== "object")
|
|
152
|
-
continue;
|
|
153
177
|
if (Array.isArray(current)) {
|
|
154
178
|
pending.push(...current);
|
|
155
179
|
continue;
|
|
156
180
|
}
|
|
157
|
-
|
|
158
|
-
|
|
181
|
+
const record = Schema2.decodeUnknownOption(Schema2.Record(Schema2.String, Schema2.Json))(current);
|
|
182
|
+
if (Option.isNone(record))
|
|
183
|
+
continue;
|
|
184
|
+
for (const [key, value] of Object.entries(record.value)) {
|
|
185
|
+
if (key === "$ref" && Schema2.is(Schema2.String)(value)) {
|
|
159
186
|
const name = value.match(/^#\/(?:\$defs|components\/schemas)\/(.+)$/)?.[1];
|
|
160
187
|
if (name && !names.has(name) && definitions[name]) {
|
|
161
188
|
names.add(name);
|
|
162
|
-
pending.push(definitions[name]);
|
|
189
|
+
pending.push(Schema2.decodeUnknownSync(Schema2.Json)(definitions[name]));
|
|
163
190
|
}
|
|
164
191
|
} else if (key !== "$defs") {
|
|
165
192
|
pending.push(value);
|
|
@@ -182,10 +209,12 @@ var httpApiOperationInputSchema = (operation) => {
|
|
|
182
209
|
...queryParameters,
|
|
183
210
|
...headerParameters
|
|
184
211
|
]) {
|
|
185
|
-
|
|
186
|
-
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
187
|
-
...parameter.description ? { description: parameter.description } : {}
|
|
212
|
+
const property = {
|
|
213
|
+
...parameter.schema ? schemaWithVisibleAnnotations(parameter.schema) : { type: "string" }
|
|
188
214
|
};
|
|
215
|
+
if (parameter.description)
|
|
216
|
+
property.description = parameter.description;
|
|
217
|
+
properties[parameter.name] = property;
|
|
189
218
|
if (parameter.required)
|
|
190
219
|
required.push(parameter.name);
|
|
191
220
|
}
|
|
@@ -201,10 +230,10 @@ var httpApiOperationInputSchema = (operation) => {
|
|
|
201
230
|
additionalProperties: false
|
|
202
231
|
};
|
|
203
232
|
};
|
|
204
|
-
var decodeJsonObject =
|
|
233
|
+
var decodeJsonObject = Schema2.decodeUnknownOption(JsonObjectSchema);
|
|
205
234
|
var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(function* (input, operation) {
|
|
206
|
-
const payload = yield*
|
|
207
|
-
const decoded = yield*
|
|
235
|
+
const payload = yield* Schema2.decodeUnknownEffect(JsonObjectSchema)(input ?? {}).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
|
|
236
|
+
const decoded = yield* Schema2.decodeUnknownEffect(HttpApiToolInputSchema)(payload).pipe(Effect2.mapError(() => new Error("Tool input must be a JSON object")));
|
|
208
237
|
const parameters = operation.parameters ?? [];
|
|
209
238
|
const pickParameters = (location) => {
|
|
210
239
|
const nestedKey = location === "path" ? "params" : location;
|
|
@@ -224,12 +253,12 @@ var decodeHttpApiOperationInput = Effect2.fn("Http.decodeApiOperationInput")(fun
|
|
|
224
253
|
var parseJsonObject = Effect2.fn("Http.parseJsonObject")(function* (value, label) {
|
|
225
254
|
if (!value)
|
|
226
255
|
return {};
|
|
227
|
-
return yield*
|
|
256
|
+
return yield* Schema2.decodeUnknownEffect(JsonObjectFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be a JSON object`)));
|
|
228
257
|
});
|
|
229
258
|
var parseJsonValue = Effect2.fn("Http.parseJsonValue")(function* (value, label) {
|
|
230
259
|
if (!value)
|
|
231
260
|
return;
|
|
232
|
-
return yield*
|
|
261
|
+
return yield* Schema2.decodeUnknownEffect(JsonValueFromString)(value).pipe(Effect2.mapError(() => new Error(`${label} must be valid JSON`)));
|
|
233
262
|
});
|
|
234
263
|
|
|
235
264
|
class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
|
|
@@ -251,10 +280,11 @@ class HttpApiSpec extends Context2.Service()("HttpApiSpec", {
|
|
|
251
280
|
});
|
|
252
281
|
const definitions = document.definitions ?? {};
|
|
253
282
|
const usedDefinitions = referencedDefinitions(document.schema, definitions);
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
283
|
+
const result = { ...document.schema };
|
|
284
|
+
if (Object.keys(usedDefinitions).length > 0) {
|
|
285
|
+
result.$defs = usedDefinitions;
|
|
286
|
+
}
|
|
287
|
+
return result;
|
|
258
288
|
};
|
|
259
289
|
return {
|
|
260
290
|
info: spec.info,
|
|
@@ -285,7 +315,7 @@ class HttpApiMcp extends Context3.Service()("HttpApiMcp", {
|
|
|
285
315
|
}) {
|
|
286
316
|
static layer = (config) => Layer3.effect(this, this.make(config));
|
|
287
317
|
}
|
|
288
|
-
var decodeStructuredContent =
|
|
318
|
+
var decodeStructuredContent = Schema3.decodeUnknownOption(JsonObjectSchema);
|
|
289
319
|
var structuredContent = (value) => decodeStructuredContent(value).pipe(Option2.getOrElse(() => ({ result: value ?? null })));
|
|
290
320
|
var toolResult = (value) => new McpSchema.CallToolResult({
|
|
291
321
|
isError: false,
|
|
@@ -303,7 +333,7 @@ var toolError = (error) => new McpSchema.CallToolResult({
|
|
|
303
333
|
});
|
|
304
334
|
var executeOperation = Effect3.fn("HttpApiMcp.executeOperation")(function* (method, path, operation, input, spec, client) {
|
|
305
335
|
const payload = yield* spec.decodeOperationInput(input, operation);
|
|
306
|
-
|
|
336
|
+
const result = yield* client.execute({
|
|
307
337
|
operation: { method, path, operation },
|
|
308
338
|
input: {
|
|
309
339
|
body: payload.body,
|
|
@@ -312,6 +342,7 @@ var executeOperation = Effect3.fn("HttpApiMcp.executeOperation")(function* (meth
|
|
|
312
342
|
query: payload.query
|
|
313
343
|
}
|
|
314
344
|
});
|
|
345
|
+
return yield* client.encodeResult(result, { method, path, operation });
|
|
315
346
|
});
|
|
316
347
|
var registerOperation = (method, path, operation, name, config, spec, client) => Effect3.gen(function* () {
|
|
317
348
|
const server = yield* McpServer.McpServer;
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
import { Effect, JsonSchema, Layer, Schema } from "effect";
|
|
2
|
+
import type { Json } from "effect/Schema";
|
|
2
3
|
import { Tool, Toolkit } from "effect/unstable/ai";
|
|
3
4
|
import { ApiClient } from "./httpapi-client.js";
|
|
4
5
|
import { HttpApiSpec, type HttpApiOperationEntry } from "./httpapi-helpers.js";
|
|
5
6
|
export type HttpApiToolkitConfig = {
|
|
6
7
|
readonly needsApproval?: (operation: HttpApiOperationEntry) => boolean;
|
|
7
8
|
readonly strict?: (operation: HttpApiOperationEntry) => boolean;
|
|
8
|
-
readonly transformResult?: (operation: HttpApiOperationEntry, result:
|
|
9
|
+
readonly transformResult?: (operation: HttpApiOperationEntry, result: Json) => Json;
|
|
9
10
|
};
|
|
10
11
|
export declare const makeOpenAiStrictJsonSchema: (schema: JsonSchema.JsonSchema) => JsonSchema.JsonSchema;
|
|
11
12
|
export declare const HttpApiToolkit: (config: HttpApiToolkitConfig) => Effect.Effect<Toolkit.Toolkit<{
|
|
12
13
|
readonly [x: string]: Tool.Tool<string, {
|
|
13
14
|
readonly parameters: Schema.Struct<{}>;
|
|
14
|
-
readonly success: Schema.
|
|
15
|
+
readonly success: Schema.Codec<Json, Json, never, never>;
|
|
15
16
|
readonly failure: Schema.String;
|
|
16
17
|
readonly failureMode: "return";
|
|
17
18
|
}, never>;
|