Fresh history cut from cynarAI/evoo antigravity-handoff/project-timeline (Voice First + project timeline). Brand docs/titles as evOo; keep @rakazo/* packages as tech debt. Excludes node_modules, caches, secrets, voice blobs.
79 lines
2.3 KiB
TypeScript
79 lines
2.3 KiB
TypeScript
import type {
|
|
AdapterContext,
|
|
ConnectorCall,
|
|
ConnectorEvent,
|
|
ConnectorProvider,
|
|
ConnectorTool,
|
|
} from "@rakazo/adapter-kit";
|
|
import { describe, expect, it } from "vitest";
|
|
import { ConnectorRegistry } from "./composio-connector.js";
|
|
import { DestinationEmulator } from "./destination-emulator.js";
|
|
|
|
class StubConnector implements ConnectorProvider {
|
|
calls: ConnectorCall[] = [];
|
|
|
|
constructor(
|
|
private readonly id: string,
|
|
private readonly tools: ConnectorTool[],
|
|
) {}
|
|
|
|
describe() {
|
|
return {
|
|
id: this.id,
|
|
contractVersion: "1",
|
|
adapterVersion: "1",
|
|
capabilities: { discover: true, oauth: false, secretsBrokered: false },
|
|
};
|
|
}
|
|
|
|
async discoverTools() {
|
|
return this.tools;
|
|
}
|
|
|
|
async *execute(call: ConnectorCall): AsyncIterable<ConnectorEvent> {
|
|
this.calls.push(call);
|
|
yield { type: "result", data: { connector: this.id, tool: call.tool } };
|
|
}
|
|
}
|
|
|
|
const context: AdapterContext = {
|
|
operationId: "test",
|
|
traceId: "test",
|
|
spaceId: "workspace",
|
|
userId: "user",
|
|
signal: new AbortController().signal,
|
|
};
|
|
|
|
describe("ConnectorRegistry", () => {
|
|
it("preserves every colliding tool and routes through hidden source metadata", async () => {
|
|
const first = new StubConnector("first", [tool("shared.tool")]);
|
|
const second = new StubConnector("second", [tool("shared.tool")]);
|
|
const registry = new ConnectorRegistry(new DestinationEmulator(), [first, second]);
|
|
|
|
const tools = await registry.discoverTools(context);
|
|
const external = tools.filter((entry) => entry.route?.connectorId !== "destination");
|
|
expect(external.map((entry) => entry.name)).toEqual(["shared.tool", "second.shared.tool"]);
|
|
|
|
const selected = external[1]!;
|
|
const results: unknown[] = [];
|
|
for await (const event of registry.execute(
|
|
{
|
|
tool: selected.name,
|
|
args: {},
|
|
executionId: "execution",
|
|
route: selected.route,
|
|
},
|
|
context,
|
|
)) {
|
|
if (event.type === "result") results.push(event.data);
|
|
}
|
|
expect(results).toEqual([{ connector: "second", tool: "shared.tool" }]);
|
|
expect(first.calls).toHaveLength(0);
|
|
expect(second.calls).toHaveLength(1);
|
|
});
|
|
});
|
|
|
|
function tool(name: string): ConnectorTool {
|
|
return { name, description: name, inputSchema: { type: "object", properties: {} } };
|
|
}
|