Showing the changes to packages/plugins/openapi/src (2 of 24 files). Show all
Unified · Split
| @@ -212,7 +212,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 211 unmodified lines | ||
| 212 | 212 | }), |
| 213 | 213 | ); |
| 214 | 214 | |
| 215 | − it.effect("registers static openapi control tools", () => | |
| 215 | + it.effect("registers static openapi executor tools", () => | |
| 216 | 216 | Effect.gen(function* () { |
| 217 | 217 | const httpClient = yield* HttpClient.HttpClient; |
| 218 | 218 | const clientLayer = Layer.succeed(HttpClient.HttpClient, httpClient); |
| @@ -228,12 +228,12 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 9 unmodified lines | ||
| 228 | 228 | |
| 229 | 229 | const tools = yield* executor.tools.list(); |
| 230 | 230 | const ids = tools.map((t) => t.id); |
| 231 | − expect(ids).toContain("openapi.previewSpec"); | |
| 232 | − expect(ids).toContain("openapi.addSource"); | |
| 231 | + expect(ids).toContain("executor.openapi.previewSpec"); | |
| 232 | + expect(ids).toContain("executor.openapi.addSource"); | |
| 233 | 233 | }), |
| 234 | 234 | ); |
| 235 | 235 | |
| 236 | − it.effect("lists openapi as a static runtime source", () => | |
| 236 | + it.effect("lists executor as the static runtime source", () => | |
| 237 | 237 | Effect.gen(function* () { |
| 238 | 238 | const httpClient = yield* HttpClient.HttpClient; |
| 239 | 239 | const clientLayer = Layer.succeed(HttpClient.HttpClient, httpClient); |
| @@ -248,7 +248,8 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 8 unmodified lines | ||
| 248 | 248 | ); |
| 249 | 249 | |
| 250 | 250 | const sources = yield* executor.sources.list(); |
| 251 | − const control = sources.find((s) => s.id === "openapi"); | |
| 251 | + expect(sources.find((s) => s.id === "openapi")).toBeUndefined(); | |
| 252 | + const control = sources.find((s) => s.id === "executor"); | |
| 252 | 253 | expect(control).toBeDefined(); |
| 253 | 254 | expect(control!.runtime).toBe(true); |
| 254 | 255 | expect(control!.canRemove).toBe(false); |
| @@ -270,7 +271,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines | ||
| 270 | 271 | ); |
| 271 | 272 | |
| 272 | 273 | const result = (yield* executor.tools.invoke( |
| 273 | − "openapi.previewSpec", | |
| 274 | + "executor.openapi.previewSpec", | |
| 274 | 275 | { spec: specJson }, |
| 275 | 276 | autoApprove, |
| 276 | 277 | )) as { operationCount: number }; |
| @@ -279,6 +280,26 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 2 unmodified lines | ||
| 279 | 280 | }), |
| 280 | 281 | ); |
| 281 | 282 | |
| 283 | + it.effect("describes static addSource parameters from Standard Schema", () => | |
| 284 | + Effect.gen(function* () { | |
| 285 | + const executor = yield* createExecutor( | |
| 286 | + makeTestConfig({ | |
| 287 | + plugins: [openApiPlugin(), memorySecretsPlugin()] as const, | |
| 288 | + }), | |
| 289 | + ); | |
| 290 | + | |
| 291 | + const schema = yield* executor.tools.schema("executor.openapi.addSource"); | |
| 292 | + | |
| 293 | + expect(schema).not.toBeNull(); | |
| 294 | + expect(schema!.inputTypeScript).toContain("scope: string"); | |
| 295 | + expect(schema!.inputTypeScript).toContain("spec: string"); | |
| 296 | + expect( | |
| 297 | + (schema!.inputSchema as { properties?: Record<string, unknown> }).properties, | |
| 298 | + ).toHaveProperty("credentialTargetScope"); | |
| 299 | + expect(schema!.inputTypeScript).not.toBe("Record<string, unknown>"); | |
| 300 | + }), | |
| 301 | + ); | |
| 302 | + | |
| 282 | 303 | it.effect("invokes static addSource through executor.tools.invoke", () => |
| 283 | 304 | Effect.gen(function* () { |
| 284 | 305 | const httpClient = yield* HttpClient.HttpClient; |
| @@ -300,7 +321,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines | ||
| 300 | 321 | ); |
| 301 | 322 | |
| 302 | 323 | const result = (yield* executor.tools.invoke( |
| 303 | − "openapi.addSource", | |
| 324 | + "executor.openapi.addSource", | |
| 304 | 325 | { scope: String(orgScope), spec: specJson, namespace: "runtime" }, |
| 305 | 326 | autoApprove, |
| 306 | 327 | )) as { sourceId: string; toolCount: number }; |
| @@ -322,7 +343,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines | ||
| 322 | 343 | |
| 323 | 344 | const declined = yield* executor.tools |
| 324 | 345 | .invoke( |
| 325 | − "openapi.addSource", | |
| 346 | + "executor.openapi.addSource", | |
| 326 | 347 | { scope: TEST_SCOPE, spec: specJson, namespace: "runtime_declined" }, |
| 327 | 348 | { onElicitation: () => Effect.succeed({ action: "decline" as const }) }, |
| 328 | 349 | ) |
| @@ -825,7 +846,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 496 unmodified lines | ||
| 825 | 846 | |
| 826 | 847 | const remaining = yield* executor.tools.list(); |
| 827 | 848 | const ids = remaining.map((t) => t.id).sort(); |
| 828 | − expect(ids).toEqual(["openapi.addSource", "openapi.previewSpec"]); | |
| 849 | + expect(ids).toEqual(["executor.openapi.addSource", "executor.openapi.previewSpec"]); | |
| 829 | 850 | }), |
| 830 | 851 | ); |
| 831 | 852 | |
| @@ -8,6 +8,7 @@ import { · 7 unmodified lines | ||
| 8 | 8 | SourceDetectionResult, |
| 9 | 9 | StorageError, |
| 10 | 10 | definePlugin, |
| 11 | + tool, | |
| 11 | 12 | resolveSecretBackedMap, |
| 12 | 13 | type CredentialBindingRef, |
| 13 | 14 | type PluginCtx, |
| @@ -169,7 +170,6 @@ const PreviewSpecInputSchema = Schema.Struct({ · 155 unmodified lines | ||
| 169 | 170 | }), |
| 170 | 171 | ), |
| 171 | 172 | }); |
| 172 | −type PreviewSpecInput = typeof PreviewSpecInputSchema.Type; | |
| 173 | 173 | |
| 174 | 174 | const OpenApiHeaderInputSchema = Schema.Union([HeaderValueSchema, ConfiguredHeaderValueSchema]); |
| 175 | 175 | const OpenApiOAuthInputSchema = OAuth2SourceConfig; |
| @@ -191,7 +191,21 @@ const AddSourceInputSchema = Schema.Struct({ · 15 unmodified lines | ||
| 191 | 191 | }), |
| 192 | 192 | ), |
| 193 | 193 | }); |
| 194 | −type AddSourceInput = typeof AddSourceInputSchema.Type; | |
| 194 | + | |
| 195 | +const AddSourceOutputSchema = Schema.Struct({ | |
| 196 | + sourceId: Schema.String, | |
| 197 | + toolCount: Schema.Number, | |
| 198 | +}); | |
| 199 | + | |
| 200 | +const PreviewSpecInputStandardSchema = Schema.toStandardSchemaV1( | |
| 201 | + Schema.toStandardJSONSchemaV1(PreviewSpecInputSchema), | |
| 202 | +); | |
| 203 | +const AddSourceInputStandardSchema = Schema.toStandardSchemaV1( | |
| 204 | + Schema.toStandardJSONSchemaV1(AddSourceInputSchema), | |
| 205 | +); | |
| 206 | +const AddSourceOutputStandardSchema = Schema.toStandardSchemaV1( | |
| 207 | + Schema.toStandardJSONSchemaV1(AddSourceOutputSchema), | |
| 208 | +); | |
| 195 | 209 | |
| 196 | 210 | // --------------------------------------------------------------------------- |
| 197 | 211 | // Helpers |
| @@ -1172,60 +1186,26 @@ export const openApiPlugin = definePlugin((options?: OpenApiPluginOptions) => { · 974 unmodified lines | ||
| 1172 | 1186 | staticSources: (self) => [ |
| 1173 | 1187 | { |
| 1174 | 1188 | id: "openapi", |
| 1175 | − kind: "control", | |
| 1189 | + kind: "executor", | |
| 1176 | 1190 | name: "OpenAPI", |
| 1177 | 1191 | tools: [ |
| 1178 | − { | |
| 1192 | + tool({ | |
| 1179 | 1193 | name: "previewSpec", |
| 1180 | 1194 | description: "Preview an OpenAPI document before adding it as a source", |
| 1181 | − inputSchema: { | |
| 1182 | − type: "object", | |
| 1183 | − properties: { | |
| 1184 | − spec: { type: "string" }, | |
| 1185 | − specFetchCredentials: { type: "object" }, | |
| 1186 | − }, | |
| 1187 | − required: ["spec"], | |
| 1188 | − }, | |
| 1189 | − handler: ({ args }) => self.previewSpec(args as PreviewSpecInput), | |
| 1190 | − }, | |
| 1191 | − { | |
| 1195 | + inputSchema: PreviewSpecInputStandardSchema, | |
| 1196 | + execute: (input) => self.previewSpec(input), | |
| 1197 | + }), | |
| 1198 | + tool({ | |
| 1192 | 1199 | name: "addSource", |
| 1193 | 1200 | description: "Add an OpenAPI source and register its operations as tools", |
| 1194 | 1201 | annotations: { |
| 1195 | 1202 | requiresApproval: true, |
| 1196 | 1203 | approvalDescription: "Add an OpenAPI source", |
| 1197 | 1204 | }, |
| 1198 | − inputSchema: { | |
| 1199 | − type: "object", | |
| 1200 | − properties: { | |
| 1201 | − scope: { type: "string" }, | |
| 1202 | − spec: { type: "string" }, | |
| 1203 | − name: { type: "string" }, | |
| 1204 | − baseUrl: { type: "string" }, | |
| 1205 | − namespace: { type: "string" }, | |
| 1206 | − headers: { type: "object" }, | |
| 1207 | − queryParams: { type: "object" }, | |
| 1208 | − oauth2: { type: "object" }, | |
| 1209 | − credentialTargetScope: { type: "string" }, | |
| 1210 | − specFetchCredentials: { type: "object" }, | |
| 1211 | − }, | |
| 1212 | − required: ["scope", "spec"], | |
| 1213 | − }, | |
| 1214 | − outputSchema: { | |
| 1215 | − type: "object", | |
| 1216 | − properties: { | |
| 1217 | − sourceId: { type: "string" }, | |
| 1218 | − toolCount: { type: "number" }, | |
| 1219 | − }, | |
| 1220 | − required: ["sourceId", "toolCount"], | |
| 1221 | − }, | |
| 1222 | − handler: ({ args }) => | |
| 1223 | − Effect.gen(function* () { | |
| 1224 | − const input: AddSourceInput = | |
| 1225 | − yield* Schema.decodeUnknownEffect(AddSourceInputSchema)(args); | |
| 1226 | − return yield* self.addSpec(input); | |
| 1227 | − }), | |
| 1228 | − }, | |
| 1205 | + inputSchema: AddSourceInputStandardSchema, | |
| 1206 | + outputSchema: AddSourceOutputStandardSchema, | |
| 1207 | + execute: (input) => self.addSpec(input), | |
| 1208 | + }), | |
| 1229 | 1209 | ], |
| 1230 | 1210 | }, |
| 1231 | 1211 | ], |