-
Notifications
You must be signed in to change notification settings - Fork 5.6k
Expand file tree
/
Copy pathProviderAdapterRegistry.test.ts
More file actions
106 lines (97 loc) · 3.5 KB
/
Copy pathProviderAdapterRegistry.test.ts
File metadata and controls
106 lines (97 loc) · 3.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import type { ProviderKind } from "@t3tools/contracts";
import { it, assert, vi } from "@effect/vitest";
import { assertFailure } from "@effect/vitest/utils";
import { Effect, Layer, Stream } from "effect";
import { ClaudeAdapter } from "../Services/ClaudeAdapter.ts";
import type { ClaudeAdapterShape } from "../Services/ClaudeAdapter.ts";
import { CodexAdapter } from "../Services/CodexAdapter.ts";
import type { CodexAdapterShape } from "../Services/CodexAdapter.ts";
import { OpenCodeAdapter } from "../Services/OpenCodeAdapter.ts";
import type { OpenCodeAdapterShape } from "../Services/OpenCodeAdapter.ts";
import { ProviderAdapterRegistry } from "../Services/ProviderAdapterRegistry.ts";
import { ProviderAdapterRegistryLive } from "./ProviderAdapterRegistry.ts";
import { ProviderUnsupportedError } from "../Errors.ts";
import * as NodeServices from "@effect/platform-node/NodeServices";
const fakeCodexAdapter: CodexAdapterShape = {
provider: "codex",
capabilities: { sessionModelSwitch: "in-session" },
startSession: vi.fn(),
sendTurn: vi.fn(),
interruptTurn: vi.fn(),
respondToRequest: vi.fn(),
respondToUserInput: vi.fn(),
stopSession: vi.fn(),
listSessions: vi.fn(),
hasSession: vi.fn(),
readThread: vi.fn(),
rollbackThread: vi.fn(),
stopAll: vi.fn(),
streamEvents: Stream.empty,
};
const fakeClaudeAdapter: ClaudeAdapterShape = {
provider: "claudeAgent",
capabilities: { sessionModelSwitch: "in-session" },
startSession: vi.fn(),
sendTurn: vi.fn(),
interruptTurn: vi.fn(),
respondToRequest: vi.fn(),
respondToUserInput: vi.fn(),
stopSession: vi.fn(),
listSessions: vi.fn(),
hasSession: vi.fn(),
readThread: vi.fn(),
rollbackThread: vi.fn(),
stopAll: vi.fn(),
streamEvents: Stream.empty,
};
const fakeOpenCodeAdapter: OpenCodeAdapterShape = {
provider: "opencode",
capabilities: { sessionModelSwitch: "in-session" },
startSession: vi.fn(),
sendTurn: vi.fn(),
interruptTurn: vi.fn(),
respondToRequest: vi.fn(),
respondToUserInput: vi.fn(),
stopSession: vi.fn(),
listSessions: vi.fn(),
hasSession: vi.fn(),
readThread: vi.fn(),
rollbackThread: vi.fn(),
stopAll: vi.fn(),
streamEvents: Stream.empty,
};
const layer = it.layer(
Layer.mergeAll(
Layer.provide(
ProviderAdapterRegistryLive,
Layer.mergeAll(
Layer.succeed(CodexAdapter, fakeCodexAdapter),
Layer.succeed(ClaudeAdapter, fakeClaudeAdapter),
Layer.succeed(OpenCodeAdapter, fakeOpenCodeAdapter),
),
),
NodeServices.layer,
),
);
layer("ProviderAdapterRegistryLive", (it) => {
it.effect("resolves a registered provider adapter", () =>
Effect.gen(function* () {
const registry = yield* ProviderAdapterRegistry;
const codex = yield* registry.getByProvider("codex");
const claude = yield* registry.getByProvider("claudeAgent");
const openCode = yield* registry.getByProvider("opencode");
assert.equal(codex, fakeCodexAdapter);
assert.equal(claude, fakeClaudeAdapter);
assert.equal(openCode, fakeOpenCodeAdapter);
const providers = yield* registry.listProviders();
assert.deepEqual(providers, ["codex", "claudeAgent", "opencode"]);
}),
);
it.effect("fails with ProviderUnsupportedError for unknown providers", () =>
Effect.gen(function* () {
const registry = yield* ProviderAdapterRegistry;
const adapter = yield* registry.getByProvider("unknown" as ProviderKind).pipe(Effect.result);
assertFailure(adapter, new ProviderUnsupportedError({ provider: "unknown" }));
}),
);
});