import { describe, expect, it } from "@effect/vitest";import { Data, Effect, Predicate, Result } from "effect"; import { ToolNotFoundError } from "./errors";import { AuthTemplateSlug, ConnectionName, IntegrationSlug, OAuthClientSlug, ProviderItemId, ProviderKey, ToolAddress, ToolName,} from "./ids";import { definePlugin } from "./plugin";import type { CredentialProvider } from "./provider";import { IntegrationDetectionResult } from "./types";import { makeTestExecutor, memoryCredentialsPlugin } from "./testing";import { serveOAuthTestServer } from "./testing/oauth-test-server"; // removed: v1 secret browser-handoff, source.configure, case-insensitive tool-id// resolution, secrets/sources/scope-stack. The integration coverage below is// ported to the v2 surface (integrations/connections/OAuth/resolveTools/execute/// tools.schema). class TestPluginError extends Data.TaggedError("TestPluginError")<{ readonly message: string;}> {} const memoryProvider = (): CredentialProvider => { const store = new Map<string, string>(); return { key: ProviderKey.make("memory"), writable: true, get: (id) => Effect.sync(() => store.get(String(id)) ?? null), set: (id, value) => Effect.sync(() => void store.set(String(id), value)), };}; const INTEG = IntegrationSlug.make("demo");const PINNED = IntegrationSlug.make("demo-pinned");const TEMPLATE = AuthTemplateSlug.make("apiKey");const CONN = ConnectionName.make("main"); const addr = (tool: string): ToolAddress => ToolAddress.make(`tools.${INTEG}.org.${CONN}.${tool}`); // ---------------------------------------------------------------------------// A plugin that registers an integration, produces per-connection tools via// resolveTools (with shared $defs), and supports ctx.transaction rollback.// --------------------------------------------------------------------------- const demoPlugin = definePlugin(() => ({ id: "demo" as const, credentialProviders: [memoryProvider()], storage: ({ pluginStorage }) => ({ put: (owner: "org" | "user", key: string, value: string) => pluginStorage.put({ collection: "item", key, owner, data: { value } }).pipe(Effect.asVoid), list: () => pluginStorage .list<{ readonly value: string }>({ collection: "item" }) .pipe(Effect.map((rows) => rows.map((row) => ({ id: row.key, value: row.data.value })))), }), resolveTools: () => Effect.succeed({ tools: [ { name: ToolName.make("inspect"), description: "inspect", inputSchema: { type: "object", properties: { pet: { $ref: "#/$defs/Pet" } }, required: ["pet"], }, outputSchema: { $ref: "#/$defs/Owner" }, }, { name: ToolName.make("run"), description: "run" }, ], definitions: { Pet: { anyOf: [{ $ref: "#/$defs/Dog" }, { $ref: "#/$defs/Cat" }] }, Dog: { type: "object", properties: { collar: { $ref: "#/$defs/Collar" } }, }, Cat: { type: "object", properties: { lives: { type: "number" } } }, Collar: { type: "object", properties: { id: { type: "string" } } }, Owner: { type: "object", properties: { pet: { $ref: "#/$defs/Pet" } } }, Unused: { type: "object", properties: { value: { type: "string" } } }, }, }), invokeTool: ({ toolRow }) => Effect.succeed({ ran: toolRow.name }), extension: (ctx) => ({ seed: () => ctx.core.integrations.register({ slug: INTEG, description: "Demo", config: {}, }), /** A catalog row the host pins in place (`canRemove: false`), the shape * `integrations.remove` has to refuse rather than drop. */ seedPinned: () => ctx.core.integrations.register({ slug: PINNED, description: "Demo (pinned)", config: {}, canRemove: false, }), storagePut: (owner: "org" | "user", key: string, value: string) => ctx.storage.put(owner, key, value), storageList: () => ctx.storage.list(), failAfterPluginAndCoreWrites: () => ctx.transaction( Effect.gen(function* () { yield* ctx.storage.put("org", "tx-row", "created-before-failure"); yield* ctx.core.integrations.register({ slug: IntegrationSlug.make("tx-integration"), description: "Tx", config: {}, }); return yield* new TestPluginError({ message: "rollback" }); }), ), }),}))(); const diagnosticsPlugin = definePlugin(() => ({ id: "diagnostics" as const, storage: () => ({}), resolveTools: ({ connection }) => Effect.succeed({ tools: [], incomplete: true, incompleteReason: "Schema introspection was rejected", ...(String(connection.integration) === "diagnostics_expired" ? { health: { status: "expired" as const, checkedAt: Date.now(), detail: "Reconnect the upstream OAuth grant", }, } : {}), }), extension: (ctx) => ({ seed: () => ctx.core.integrations.register({ slug: IntegrationSlug.make("diagnostics"), description: "Diagnostics", config: {}, }), seedExpired: () => ctx.core.integrations.register({ slug: IntegrationSlug.make("diagnostics_expired"), description: "Expired diagnostics", config: {}, }), }),}))(); const detector = (id: string, confidence: IntegrationDetectionResult["confidence"]) => definePlugin(() => ({ id, storage: () => ({}), detect: () => Effect.succeed( IntegrationDetectionResult.make({ kind: id, confidence, endpoint: `https://example.com/${id}`, name: id, slug: id, }), ), }))(); describe("createExecutor", () => { it.effect("rolls back plugin and core writes from ctx.transaction failures", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, }); const result = yield* Effect.result(executor.demo.failAfterPluginAndCoreWrites()); expect(Result.isFailure(result)).toBe(true); // Neither the plugin row nor the core integration row should survive. const rows = yield* executor.demo.storageList(); expect(rows).toEqual([]); const integrations = yield* executor.integrations.list(); expect(integrations.map((i) => String(i.slug))).not.toContain("tx-integration"); }), ); it.effect("runs plugin close hooks", () => Effect.gen(function* () { let closed = false; const closingPlugin = definePlugin(() => ({ id: "closing" as const, storage: () => ({}), close: () => Effect.sync(() => void (closed = true)), }))(); const executor = yield* makeTestExecutor({ plugins: [closingPlugin] as const, }); yield* executor.close(); expect(closed).toBe(true); }), ); it.effect("notifies onIntegrationChange on create and remove, not on re-register", () => Effect.gen(function* () { const events: Array<{ kind: string; pluginKey: string; slug: string }> = []; const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: (event) => Effect.sync(() => { events.push({ kind: event.kind, pluginKey: event.pluginKey, slug: String(event.slug), }); }), }); yield* executor.demo.seed(); expect(events).toEqual([{ kind: "added", pluginKey: "demo", slug: String(INTEG) }]); // Upsert re-register of the same slug is not a durable change. yield* executor.demo.seed(); expect(events).toHaveLength(1); yield* executor.integrations.remove(INTEG); expect(events).toEqual([ { kind: "added", pluginKey: "demo", slug: String(INTEG) }, { kind: "removed", pluginKey: "demo", slug: String(INTEG) }, ]); // Removing an already-absent slug notifies nothing. yield* executor.integrations.remove(INTEG); expect(events).toHaveLength(2); }), ); it.effect("a failing onIntegrationChange observer never fails the operation", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: () => Effect.die("observer exploded"), }); yield* executor.demo.seed(); const integrations = yield* executor.integrations.list(); expect(integrations.map((i) => String(i.slug))).toContain(String(INTEG)); }), ); it.effect("a rolled-back transaction never notifies onIntegrationChange", () => Effect.gen(function* () { const events: string[] = []; const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: (event) => Effect.sync(() => void events.push(String(event.slug))), }); const result = yield* Effect.result(executor.demo.failAfterPluginAndCoreWrites()); expect(Result.isFailure(result)).toBe(true); expect(events).not.toContain("tx-integration"); }), ); it.effect("projects core tools as the built-in Executor integration", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ coreTools: { webBaseUrl: "http://localhost:3000" }, }); const integrations = yield* executor.integrations.list(); const executorIntegration = integrations.find((i) => String(i.slug) === "executor"); expect(executorIntegration).toMatchObject({ description: "Executor", kind: "built-in", canRemove: false, canRefresh: false, }); const address = ToolAddress.make("executor.coreTools.integrations.list"); const tools = yield* executor.tools.list({ integration: IntegrationSlug.make("executor"), includeBlocked: true, }); const listed = tools.find((toolRow) => toolRow.address === address); expect(listed).toMatchObject({ address, integration: IntegrationSlug.make("executor"), connection: ConnectionName.make("coreTools"), name: ToolName.make("coreTools.integrations.list"), static: true, }); const schema = yield* executor.tools.schema(address); expect(schema).toMatchObject({ address, name: "coreTools.integrations.list", outputSchema: { type: "object", required: ["integrations"], }, }); const out = yield* executor.execute(address, {}); expect(out).toMatchObject({ integrations: [expect.objectContaining({ slug: "executor" })], }); }), ); it.effect("can omit provider tools from the built-in Executor integration", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ coreTools: { webBaseUrl: "http://localhost:3000", includeProviders: false, }, }); const tools = yield* executor.tools.list({ integration: IntegrationSlug.make("executor"), includeBlocked: true, }); const names = tools.map((toolRow) => String(toolRow.name)).sort(); expect(names).toContain("coreTools.integrations.list"); expect(names).not.toContain("coreTools.providers.list"); expect(names).not.toContain("coreTools.providers.items"); }), ); it.effect("creates provider-backed connections through the built-in Executor tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, coreTools: { webBaseUrl: "http://localhost:3000" }, }); yield* executor.demo.seed(); const created = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), identityLabel: "Demo", from: { provider: "memory", id: "secret-token" }, }, ); expect(created).toMatchObject({ owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), address: "tools.demo.org.main", identityLabel: "Demo", oauthClient: null, }); const listed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.list"), { integration: String(INTEG), owner: "org" }, ); expect(listed).toMatchObject({ connections: [expect.objectContaining({ address: "tools.demo.org.main" })], }); const out = yield* executor.execute(addr("run"), {}); expect(out).toEqual({ ran: "run" }); }), ); it.effect("removes catalog integrations through the built-in Executor tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, coreTools: {}, }); yield* executor.demo.seed(); yield* executor.demo.seedPinned(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), from: { provider: "memory", id: "secret-token" }, }, { onElicitation: "accept-all" }, ); const remove = ToolAddress.make("executor.coreTools.integrations.remove"); // Removing the integration cascades to the connections under it. const removed = yield* executor.execute( remove, { slug: String(INTEG) }, { onElicitation: "accept-all" }, ); expect(removed).toEqual({ removed: true }); const listed = yield* executor.integrations.list(); expect(listed.map((integration) => String(integration.slug))).not.toContain(String(INTEG)); expect(yield* executor.connections.list()).toHaveLength(0); // An already-absent slug and a built-in namespace both report honestly // instead of claiming a removal that never happened. expect( yield* executor.execute(remove, { slug: String(INTEG) }, { onElicitation: "accept-all" }), ).toEqual({ removed: false }); expect( yield* executor.execute(remove, { slug: "executor" }, { onElicitation: "accept-all" }), ).toEqual({ removed: false }); // A pinned integration is refused, and survives the attempt. const refused = yield* Effect.result( executor.execute(remove, { slug: String(PINNED) }, { onElicitation: "accept-all" }), ); expect(Result.isFailure(refused)).toBe(true); if (!Result.isFailure(refused)) return; expect(Predicate.isTagged(refused.failure, "ToolInvocationError")).toBe(true); expect( Predicate.isTagged( (refused.failure as { readonly cause?: unknown }).cause, "IntegrationRemovalNotAllowedError", ), ).toBe(true); const afterRefusal = yield* executor.integrations.list(); expect(afterRefusal.map((integration) => String(integration.slug))).toContain(String(PINNED)); }), ); it.effect("surfaces failed tool sync diagnostics through connection tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [memoryCredentialsPlugin(), diagnosticsPlugin] as const, coreTools: {}, }); yield* executor.diagnostics.seed(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: "main", integration: "diagnostics", template: "none", }, { onElicitation: "accept-all" }, ); const listed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.list"), { integration: "diagnostics", verbose: true }, ); expect(listed).toMatchObject({ connections: [ { lastHealth: { status: "degraded", detail: "Tool sync failing: Schema introspection was rejected", }, }, ], }); const refreshed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.refresh"), { owner: "org", name: "main", integration: "diagnostics", }, { onElicitation: "accept-all" }, ); expect(refreshed).toMatchObject({ tools: [], lastHealth: { status: "degraded", detail: "Tool sync failing: Schema introspection was rejected", }, }); }), ); it.effect("preserves actionable health from an incomplete tool catalog", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [memoryCredentialsPlugin(), diagnosticsPlugin] as const, coreTools: {}, }); yield* executor.diagnostics.seedExpired(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: "main",Lines 1–500 of 785. Load more
import { describe, expect, it } from "@effect/vitest"; import { Data, Effect, Predicate, Result } from "effect"; import { ToolNotFoundError } from "./errors"; import { AuthTemplateSlug, ConnectionName, IntegrationSlug, OAuthClientSlug, ProviderItemId, ProviderKey, ToolAddress, ToolName, } from "./ids"; import { definePlugin } from "./plugin"; import type { CredentialProvider } from "./provider"; import { IntegrationDetectionResult } from "./types"; import { makeTestExecutor, memoryCredentialsPlugin } from "./testing"; import { serveOAuthTestServer } from "./testing/oauth-test-server"; // removed: v1 secret browser-handoff, source.configure, case-insensitive tool-id // resolution, secrets/sources/scope-stack. The integration coverage below is // ported to the v2 surface (integrations/connections/OAuth/resolveTools/execute/ // tools.schema). class TestPluginError extends Data.TaggedError("TestPluginError")<{ readonly message: string; }> {} const memoryProvider = (): CredentialProvider => { const store = new Map<string, string>(); return { key: ProviderKey.make("memory"), writable: true, get: (id) => Effect.sync(() => store.get(String(id)) ?? null), set: (id, value) => Effect.sync(() => void store.set(String(id), value)), }; }; const INTEG = IntegrationSlug.make("demo"); const PINNED = IntegrationSlug.make("demo-pinned"); const TEMPLATE = AuthTemplateSlug.make("apiKey"); const CONN = ConnectionName.make("main"); const addr = (tool: string): ToolAddress => ToolAddress.make(`tools.${INTEG}.org.${CONN}.${tool}`); // --------------------------------------------------------------------------- // A plugin that registers an integration, produces per-connection tools via // resolveTools (with shared $defs), and supports ctx.transaction rollback. // --------------------------------------------------------------------------- const demoPlugin = definePlugin(() => ({ id: "demo" as const, credentialProviders: [memoryProvider()], storage: ({ pluginStorage }) => ({ put: (owner: "org" | "user", key: string, value: string) => pluginStorage.put({ collection: "item", key, owner, data: { value } }).pipe(Effect.asVoid), list: () => pluginStorage .list<{ readonly value: string }>({ collection: "item" }) .pipe(Effect.map((rows) => rows.map((row) => ({ id: row.key, value: row.data.value })))), }), resolveTools: () => Effect.succeed({ tools: [ { name: ToolName.make("inspect"), description: "inspect", inputSchema: { type: "object", properties: { pet: { $ref: "#/$defs/Pet" } }, required: ["pet"], }, outputSchema: { $ref: "#/$defs/Owner" }, }, { name: ToolName.make("run"), description: "run" }, ], definitions: { Pet: { anyOf: [{ $ref: "#/$defs/Dog" }, { $ref: "#/$defs/Cat" }] }, Dog: { type: "object", properties: { collar: { $ref: "#/$defs/Collar" } }, }, Cat: { type: "object", properties: { lives: { type: "number" } } }, Collar: { type: "object", properties: { id: { type: "string" } } }, Owner: { type: "object", properties: { pet: { $ref: "#/$defs/Pet" } } }, Unused: { type: "object", properties: { value: { type: "string" } } }, }, }), invokeTool: ({ toolRow }) => Effect.succeed({ ran: toolRow.name }), extension: (ctx) => ({ seed: () => ctx.core.integrations.register({ slug: INTEG, description: "Demo", config: {}, }), /** A catalog row the host pins in place (`canRemove: false`), the shape * `integrations.remove` has to refuse rather than drop. */ seedPinned: () => ctx.core.integrations.register({ slug: PINNED, description: "Demo (pinned)", config: {}, canRemove: false, }), storagePut: (owner: "org" | "user", key: string, value: string) => ctx.storage.put(owner, key, value), storageList: () => ctx.storage.list(), failAfterPluginAndCoreWrites: () => ctx.transaction( Effect.gen(function* () { yield* ctx.storage.put("org", "tx-row", "created-before-failure"); yield* ctx.core.integrations.register({ slug: IntegrationSlug.make("tx-integration"), description: "Tx", config: {}, }); return yield* new TestPluginError({ message: "rollback" }); }), ), }), }))(); const diagnosticsPlugin = definePlugin(() => ({ id: "diagnostics" as const, storage: () => ({}), resolveTools: ({ connection }) => Effect.succeed({ tools: [], incomplete: true, incompleteReason: "Schema introspection was rejected", ...(String(connection.integration) === "diagnostics_expired" ? { health: { status: "expired" as const, checkedAt: Date.now(), detail: "Reconnect the upstream OAuth grant", }, } : {}), }), extension: (ctx) => ({ seed: () => ctx.core.integrations.register({ slug: IntegrationSlug.make("diagnostics"), description: "Diagnostics", config: {}, }), seedExpired: () => ctx.core.integrations.register({ slug: IntegrationSlug.make("diagnostics_expired"), description: "Expired diagnostics", config: {}, }), }), }))(); const detector = (id: string, confidence: IntegrationDetectionResult["confidence"]) => definePlugin(() => ({ id, storage: () => ({}), detect: () => Effect.succeed( IntegrationDetectionResult.make({ kind: id, confidence, endpoint: `https://example.com/${id}`, name: id, slug: id, }), ), }))(); describe("createExecutor", () => { it.effect("rolls back plugin and core writes from ctx.transaction failures", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, }); const result = yield* Effect.result(executor.demo.failAfterPluginAndCoreWrites()); expect(Result.isFailure(result)).toBe(true); // Neither the plugin row nor the core integration row should survive. const rows = yield* executor.demo.storageList(); expect(rows).toEqual([]); const integrations = yield* executor.integrations.list(); expect(integrations.map((i) => String(i.slug))).not.toContain("tx-integration"); }), ); it.effect("runs plugin close hooks", () => Effect.gen(function* () { let closed = false; const closingPlugin = definePlugin(() => ({ id: "closing" as const, storage: () => ({}), close: () => Effect.sync(() => void (closed = true)), }))(); const executor = yield* makeTestExecutor({ plugins: [closingPlugin] as const, }); yield* executor.close(); expect(closed).toBe(true); }), ); it.effect("notifies onIntegrationChange on create and remove, not on re-register", () => Effect.gen(function* () { const events: Array<{ kind: string; pluginKey: string; slug: string }> = []; const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: (event) => Effect.sync(() => { events.push({ kind: event.kind, pluginKey: event.pluginKey, slug: String(event.slug), }); }), }); yield* executor.demo.seed(); expect(events).toEqual([{ kind: "added", pluginKey: "demo", slug: String(INTEG) }]); // Upsert re-register of the same slug is not a durable change. yield* executor.demo.seed(); expect(events).toHaveLength(1); yield* executor.integrations.remove(INTEG); expect(events).toEqual([ { kind: "added", pluginKey: "demo", slug: String(INTEG) }, { kind: "removed", pluginKey: "demo", slug: String(INTEG) }, ]); // Removing an already-absent slug notifies nothing. yield* executor.integrations.remove(INTEG); expect(events).toHaveLength(2); }), ); it.effect("a failing onIntegrationChange observer never fails the operation", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: () => Effect.die("observer exploded"), }); yield* executor.demo.seed(); const integrations = yield* executor.integrations.list(); expect(integrations.map((i) => String(i.slug))).toContain(String(INTEG)); }), ); it.effect("a rolled-back transaction never notifies onIntegrationChange", () => Effect.gen(function* () { const events: string[] = []; const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, onIntegrationChange: (event) => Effect.sync(() => void events.push(String(event.slug))), }); const result = yield* Effect.result(executor.demo.failAfterPluginAndCoreWrites()); expect(Result.isFailure(result)).toBe(true); expect(events).not.toContain("tx-integration"); }), ); it.effect("projects core tools as the built-in Executor integration", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ coreTools: { webBaseUrl: "http://localhost:3000" }, }); const integrations = yield* executor.integrations.list(); const executorIntegration = integrations.find((i) => String(i.slug) === "executor"); expect(executorIntegration).toMatchObject({ description: "Executor", kind: "built-in", canRemove: false, canRefresh: false, }); const address = ToolAddress.make("executor.coreTools.integrations.list"); const tools = yield* executor.tools.list({ integration: IntegrationSlug.make("executor"), includeBlocked: true, }); const listed = tools.find((toolRow) => toolRow.address === address); expect(listed).toMatchObject({ address, integration: IntegrationSlug.make("executor"), connection: ConnectionName.make("coreTools"), name: ToolName.make("coreTools.integrations.list"), static: true, }); const schema = yield* executor.tools.schema(address); expect(schema).toMatchObject({ address, name: "coreTools.integrations.list", outputSchema: { type: "object", required: ["integrations"], }, }); const out = yield* executor.execute(address, {}); expect(out).toMatchObject({ integrations: [expect.objectContaining({ slug: "executor" })], }); }), ); it.effect("can omit provider tools from the built-in Executor integration", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ coreTools: { webBaseUrl: "http://localhost:3000", includeProviders: false, }, }); const tools = yield* executor.tools.list({ integration: IntegrationSlug.make("executor"), includeBlocked: true, }); const names = tools.map((toolRow) => String(toolRow.name)).sort(); expect(names).toContain("coreTools.integrations.list"); expect(names).not.toContain("coreTools.providers.list"); expect(names).not.toContain("coreTools.providers.items"); }), ); it.effect("creates provider-backed connections through the built-in Executor tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, coreTools: { webBaseUrl: "http://localhost:3000" }, }); yield* executor.demo.seed(); const created = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), identityLabel: "Demo", from: { provider: "memory", id: "secret-token" }, }, ); expect(created).toMatchObject({ owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), address: "tools.demo.org.main", identityLabel: "Demo", oauthClient: null, }); const listed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.list"), { integration: String(INTEG), owner: "org" }, ); expect(listed).toMatchObject({ connections: [expect.objectContaining({ address: "tools.demo.org.main" })], }); const out = yield* executor.execute(addr("run"), {}); expect(out).toEqual({ ran: "run" }); }), ); it.effect("removes catalog integrations through the built-in Executor tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [demoPlugin] as const, coreTools: {}, }); yield* executor.demo.seed(); yield* executor.demo.seedPinned(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: String(CONN), integration: String(INTEG), template: String(TEMPLATE), from: { provider: "memory", id: "secret-token" }, }, { onElicitation: "accept-all" }, ); const remove = ToolAddress.make("executor.coreTools.integrations.remove"); // Removing the integration cascades to the connections under it. const removed = yield* executor.execute( remove, { slug: String(INTEG) }, { onElicitation: "accept-all" }, ); expect(removed).toEqual({ removed: true }); const listed = yield* executor.integrations.list(); expect(listed.map((integration) => String(integration.slug))).not.toContain(String(INTEG)); expect(yield* executor.connections.list()).toHaveLength(0); // An already-absent slug and a built-in namespace both report honestly // instead of claiming a removal that never happened. expect( yield* executor.execute(remove, { slug: String(INTEG) }, { onElicitation: "accept-all" }), ).toEqual({ removed: false }); expect( yield* executor.execute(remove, { slug: "executor" }, { onElicitation: "accept-all" }), ).toEqual({ removed: false }); // A pinned integration is refused, and survives the attempt. const refused = yield* Effect.result( executor.execute(remove, { slug: String(PINNED) }, { onElicitation: "accept-all" }), ); expect(Result.isFailure(refused)).toBe(true); if (!Result.isFailure(refused)) return; expect(Predicate.isTagged(refused.failure, "ToolInvocationError")).toBe(true); expect( Predicate.isTagged( (refused.failure as { readonly cause?: unknown }).cause, "IntegrationRemovalNotAllowedError", ), ).toBe(true); const afterRefusal = yield* executor.integrations.list(); expect(afterRefusal.map((integration) => String(integration.slug))).toContain(String(PINNED)); }), ); it.effect("surfaces failed tool sync diagnostics through connection tools", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [memoryCredentialsPlugin(), diagnosticsPlugin] as const, coreTools: {}, }); yield* executor.diagnostics.seed(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: "main", integration: "diagnostics", template: "none", }, { onElicitation: "accept-all" }, ); const listed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.list"), { integration: "diagnostics", verbose: true }, ); expect(listed).toMatchObject({ connections: [ { lastHealth: { status: "degraded", detail: "Tool sync failing: Schema introspection was rejected", }, }, ], }); const refreshed = yield* executor.execute( ToolAddress.make("executor.coreTools.connections.refresh"), { owner: "org", name: "main", integration: "diagnostics", }, { onElicitation: "accept-all" }, ); expect(refreshed).toMatchObject({ tools: [], lastHealth: { status: "degraded", detail: "Tool sync failing: Schema introspection was rejected", }, }); }), ); it.effect("preserves actionable health from an incomplete tool catalog", () => Effect.gen(function* () { const executor = yield* makeTestExecutor({ plugins: [memoryCredentialsPlugin(), diagnosticsPlugin] as const, coreTools: {}, }); yield* executor.diagnostics.seedExpired(); yield* executor.execute( ToolAddress.make("executor.coreTools.connections.create"), { owner: "org", name: "main",