History

Move control tools under executor namespace (#756)

Rhys Sullivan committed 6 months ago

Commit 65bd2ff1 parent d80571124 files · +329 −200Browse files

Showing the changes to packages/plugins/openapi/src (2 of 24 files). Show all

Unified · Split

2 files
  1. packages/plugins/openapi/src/sdk/plugin.test.ts +30 −9
  2. packages/plugins/openapi/src/sdk/plugin.ts +26 −46
packages/plugins/openapi/src/sdk/plugin.test.ts+30−9
@@ -212,7 +212,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 211 unmodified lines
212212 }),
213213 );
214214
215− it.effect("registers static openapi control tools", () =>
215+ it.effect("registers static openapi executor tools", () =>
216216 Effect.gen(function* () {
217217 const httpClient = yield* HttpClient.HttpClient;
218218 const clientLayer = Layer.succeed(HttpClient.HttpClient, httpClient);
@@ -228,12 +228,12 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 9 unmodified lines
228228
229229 const tools = yield* executor.tools.list();
230230 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");
233233 }),
234234 );
235235
236− it.effect("lists openapi as a static runtime source", () =>
236+ it.effect("lists executor as the static runtime source", () =>
237237 Effect.gen(function* () {
238238 const httpClient = yield* HttpClient.HttpClient;
239239 const clientLayer = Layer.succeed(HttpClient.HttpClient, httpClient);
@@ -248,7 +248,8 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 8 unmodified lines
248248 );
249249
250250 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");
252253 expect(control).toBeDefined();
253254 expect(control!.runtime).toBe(true);
254255 expect(control!.canRemove).toBe(false);
@@ -270,7 +271,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines
270271 );
271272
272273 const result = (yield* executor.tools.invoke(
273− "openapi.previewSpec",
274+ "executor.openapi.previewSpec",
274275 { spec: specJson },
275276 autoApprove,
276277 )) as { operationCount: number };
@@ -279,6 +280,26 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 2 unmodified lines
279280 }),
280281 );
281282
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+
282303 it.effect("invokes static addSource through executor.tools.invoke", () =>
283304 Effect.gen(function* () {
284305 const httpClient = yield* HttpClient.HttpClient;
@@ -300,7 +321,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines
300321 );
301322
302323 const result = (yield* executor.tools.invoke(
303− "openapi.addSource",
324+ "executor.openapi.addSource",
304325 { scope: String(orgScope), spec: specJson, namespace: "runtime" },
305326 autoApprove,
306327 )) as { sourceId: string; toolCount: number };
@@ -322,7 +343,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 15 unmodified lines
322343
323344 const declined = yield* executor.tools
324345 .invoke(
325− "openapi.addSource",
346+ "executor.openapi.addSource",
326347 { scope: TEST_SCOPE, spec: specJson, namespace: "runtime_declined" },
327348 { onElicitation: () => Effect.succeed({ action: "decline" as const }) },
328349 )
@@ -825,7 +846,7 @@ layer(TestLayer)("OpenAPI Plugin", (it) => { · 496 unmodified lines
825846
826847 const remaining = yield* executor.tools.list();
827848 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"]);
829850 }),
830851 );
831852
packages/plugins/openapi/src/sdk/plugin.ts+26−46
@@ -8,6 +8,7 @@ import { · 7 unmodified lines
88 SourceDetectionResult,
99 StorageError,
1010 definePlugin,
11+ tool,
1112 resolveSecretBackedMap,
1213 type CredentialBindingRef,
1314 type PluginCtx,
@@ -169,7 +170,6 @@ const PreviewSpecInputSchema = Schema.Struct({ · 155 unmodified lines
169170 }),
170171 ),
171172 });
172−type PreviewSpecInput = typeof PreviewSpecInputSchema.Type;
173173
174174 const OpenApiHeaderInputSchema = Schema.Union([HeaderValueSchema, ConfiguredHeaderValueSchema]);
175175 const OpenApiOAuthInputSchema = OAuth2SourceConfig;
@@ -191,7 +191,21 @@ const AddSourceInputSchema = Schema.Struct({ · 15 unmodified lines
191191 }),
192192 ),
193193 });
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+);
195209
196210 // ---------------------------------------------------------------------------
197211 // Helpers
@@ -1172,60 +1186,26 @@ export const openApiPlugin = definePlugin((options?: OpenApiPluginOptions) => { · 974 unmodified lines
11721186 staticSources: (self) => [
11731187 {
11741188 id: "openapi",
1175− kind: "control",
1189+ kind: "executor",
11761190 name: "OpenAPI",
11771191 tools: [
1178− {
1192+ tool({
11791193 name: "previewSpec",
11801194 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({
11921199 name: "addSource",
11931200 description: "Add an OpenAPI source and register its operations as tools",
11941201 annotations: {
11951202 requiresApproval: true,
11961203 approvalDescription: "Add an OpenAPI source",
11971204 },
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+ }),
12291209 ],
12301210 },
12311211 ],